Kafka 设计之消息传递保障

2024-03-08 09:04

本文主要是介绍Kafka 设计之消息传递保障,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一. 前言

二. Kafka 消息传递保障设计


一. 前言

    消息传递保障对于分布式系统的可靠性至关重要。在分布式系统中消息传递保障是确保系统可靠性的核心问题之一。系统需要确保消息能够按照预期的方式进行传递,以满足业务需求。

    Kafka 是一种分布式的消息队列系统,作为消息中间件常用于实现基于发布/订阅模型的消息传递服务。因此在 Kafka 中需要提供消息传递保障。

二. Kafka 消息传递保障设计

原文引用:Now that we understand a little about how producers and consumers work, let's discuss the semantic guarantees Kafka provides between producer and consumer. Clearly there are multiple possible message delivery guarantees that could be provided:

  • At most once—Messages may be lost but are never redelivered.
  • At least once—Messages are never lost but may be redelivered.
  • Exactly once—this is what people actually want, each message is delivered once and only once.

    现在我们了解一些关于生产者和消费者是如何工作的,接下来我们来讨论 Kafka 提供了生产者和消费者之间的担保语义。有多种可能的消息传递保证可以提供:

  • 最多一次 ---- 消息可能丢失,但绝不会重发。
  • 至少一次 ---- 消息绝不会丢失,但有可能重新发送。
  • 正好一次 ---- 这是人们真正想要的,每个消息传递一次且仅一次。

原文引用:It's worth noting that this breaks down into two problems: the durability guarantees for publishing a message and the guarantees when consuming a message. 

    值得注意的是,这分为两个问题:发送消息时的持久性保证和消费消息的保障。

原文引用:Many systems claim to provide "exactly once" delivery semantics, but it is important to read the fine print, most of these claims are misleading (i.e. they don't translate to the case where consumers or producers can fail, or cases where there are multiple consumer processes, or cases where data written to disk can be lost). 

    很多消息系统声称提供“正好一次”的传递语义,但阅读细节很重要,这些说法大多具有误导性(例如,它们没有解释消费者或生产者可能失败的情况,有多个消费者进程的情况,或写入磁盘的数据可能丢失的情况)。

原文引用:Kafka's semantics are straight-forward. When publishing a message we have a notion of the message being "committed" to the log. Once a published message is committed it will not be lost as long as one broker that replicates the partition to which this message was written remains "alive". The definition of alive as well as a description of which types of failures we attempt to handle will be described in more detail in the next section. For now let's assume a perfect, lossless broker and try to understand the guarantees to the producer and consumer. If a producer attempts to publish a message and experiences a network error it cannot be sure if this error happened before or after the message was committed. This is similar to the semantics of inserting into a database table with an autogenerated key. 

    Kafka 的语义是很直接的,我们有一个概念,当发布一条消息时,该消息 “committed(提交)” 到了日志,一旦提交了已发布的消息,只要副本分区写入了此消息的一个 Broker 仍然"活着”,它就不会丢失。“活着”的定义以及以及我们试图处理的故障类型的描述将在下一节中进行更详细的描述。现在让我们假设一个完美的不会丢消息的 Broker,并去了解如何保障生产者和消费者的。如果一个生产者发布消息并且正好遇到网络错误,就不能确定已提交的消息是否是在这个错误发生之前或之后。这类似于用自动生成的键插入到一个数据库表。

原文引用:Prior to 0.11.0.0, if a producer failed to receive a response indicating that a message was committed, it had little choice but to resend the message. This provides at-least-once delivery semantics since the message may be written to the log again during resending if the original request had in fact succeeded. Since 0.11.0.0, the Kafka producer also supports an idempotent delivery option which guarantees that resending will not result in duplicate entries in the log. To achieve this, the broker assigns each producer an ID and deduplicates messages using a sequence number that is sent by the producer along with every message. Also beginning with 0.11.0.0, the producer supports the ability to send messages to multiple topic partitions using transaction-like semantics: i.e. either all messages are successfully written or none of them are. The main use case for this is exactly-once processing between Kafka topics (described below).

    在0.11.0.0之前,如果一个生产者没有收到消息提交的响应,那么只能重新发送消息。 这提供了至少一次传递保障,因为如果原始请求实际上已成功,则消息可以在重新发送期间再次写入到日志中。自0.11.0.0起,Kafka 生产者支持幂等传递选项,保证重新发送不会导致日志中数据重复。 Broker 为每个生产者分配一个 ID,并使用生产者与每条消息一起发送的序列号为每条消息进行去重。从0.11.0.0开始,生产者支持使用类似事务的语义将消息发送到多个 Topic 分区的能力:即要么所有消息都成功写入,要么都没有成功写入。这个主要用于 Kafka Topic 之间“正好一次”的处理(如下所述)。

原文引用:Not all use cases require such strong guarantees. For uses which are latency sensitive we allow the producer to specify the durability level it desires. If the producer specifies that it wants to wait on the message being committed this can take on the order of 10 ms. However the producer can also specify that it wants to perform the send completely asynchronously or that it wants to wait only until the leader (but not necessarily the followers) have the message.

    并不是所有的情况都需要这么强力的保障。对于延迟敏感的,我们允许生产者指定它想要的耐用性水平。如生产者可以指定它获取需等待10毫秒量级上的响应。生产者也可以指定异步发送,或只等待 Leader(不需要副本的响应)响应。

原文引用:Now let's describe the semantics from the point-of-view of the consumer. All replicas have the exact same log with the same offsets. The consumer controls its position in this log. If the consumer never crashed it could just store this position in memory, but if the consumer fails and we want this topic partition to be taken over by another process the new process will need to choose an appropriate position from which to start processing. Let's say the consumer reads some messages -- it has several options for processing the messages and updating its position.

  1. It can read the messages, then save its position in the log, and finally process the messages. In this case there is a possibility that the consumer process crashes after saving its position but before saving the output of its message processing. In this case the process that took over processing would start at the saved position even though a few messages prior to that position had not been processed. This corresponds to "at-most-once" semantics as in the case of a consumer failure messages may not be processed.
  2. It can read the messages, process the messages, and finally save its position. In this case there is a possibility that the consumer process crashes after processing messages but before saving its position. In this case when the new process takes over the first few messages it receives will already have been processed. This corresponds to the "at-least-once" semantics in the case of consumer failure. In many cases messages have a primary key and so the updates are idempotent (receiving the same message twice just overwrites a record with another copy of itself).

    现在让我们从消费者的角度描述语义。所有的副本都有相同的日志、相同的偏移量。消费者控制offset 在日志中的位置。如果消费者永不宕机,它可以将此位置存储在内存中,但是如果消费者故障,我们希望这个 Topic 分区被另一个进程接管,新进程需要选择一个合适的位置开始处理。我们假设消费者读取了一些消息,有几种选项用于处理消息和更新它的位置。

  1. 读取消息,然后在日志中保存它的位置,最后处理消息。在这种情况下,有可能消费者保存了位置之后,但是在处理消息输出之前崩溃了。在这种情况下,接管处理的进程会在已保存的位置开始,即使该位置之前有几个消息尚未处理。这对应于“最多一次” ,在消费者处理失败消息的情况下,不进行处理。
  2. 读取消息,处理消息,最后保存消息的位置。在这种情况下,可能消费进程处理消息之后,但在保存它的位置之前崩溃了。在这种情况下,当新的进程接管了它,这将接收已经被处理的前几个消息。这就符合了“至少一次”的语义。在许多情况下,消息有一个主键,因此更新是幂等的(其任意多次执行所产生的影响均与一次执行的影响相同)。

原文引用:So what about exactly once semantics (i.e. the thing you actually want)? When consuming from a Kafka topic and producing to another topic (as in a Kafka Streams application), we can leverage the new transactional producer capabilities in 0.11.0.0 that were mentioned above. The consumer's position is stored as a message in a topic, so we can write the offset to Kafka in the same transaction as the output topics receiving the processed data. If the transaction is aborted, the consumer's position will revert to its old value and the produced data on the output topics will not be visible to other consumers, depending on their "isolation level." In the default "read_uncommitted" isolation level, all messages are visible to consumers even if they were part of an aborted transaction, but in "read_committed," the consumer will only return messages from transactions which were committed (and any messages which were not part of a transaction).

    那么,什么是“正好一次”语义(也就是你真正想要的东西)呢? 当从 Kafka 主题消费并生产到另一个 Topic 时(例如 Kafka Stream),我们可以利用之前提到0.11.0.0中的生产者新事务功能。消费者的位置作为消息存储到 Topic 中,因此我们可以与接收处理后的数据的输出 Topic 使用相同的事务写入 offset 到 Kafka。如果事务中断,则消费者的位置将恢复到老的值,根据其“隔离级别”,其他消费者将不会看到输出 Topic 的生成数据,在默认的“read_uncommitted”隔离级别中,所有消息对消费者都是可见的,即使是被中断的事务的消息。但是在“read_committed”中,消费者将只返回已提交事务的消息。

原文引用:When writing to an external system, the limitation is in the need to coordinate the consumer's position with what is actually stored as output. The classic way of achieving this would be to introduce a two-phase commit between the storage of the consumer position and the storage of the consumers output. But this can be handled more simply and generally by letting the consumer store its offset in the same place as its output. This is better because many of the output systems a consumer might want to write to will not support a two-phase commit. As an example of this, consider a Kafka Connect connector which populates data in HDFS along with the offsets of the data it reads so that it is guaranteed that either data and offsets are both updated or neither is. We follow similar patterns for many other data systems which require these stronger semantics and for which the messages do not have a primary key to allow for deduplication.

    当写入到外部系统时,需要将消费者的位置与实际存储为输出的位置进行协调。实现这一目标的典型方法是在消费者位置的存储和消费者输出的存储之间引入两阶段提交。但是,这可以通过让消费者将其 offset 存储在与其输出相同的位置来更简单、更普遍地处理。这样更好,因为大多数的输出系统不支持两阶段提交。举个例子,考虑一个 Kafka Connect 连接器,它在 HDFS 中填充数据以及它读取的数据的 offset,这样就可以保证数据和 offset 都被更新或者都不更新。我们对许多其他数据系统采用了类似的模式,这些系统需要这些更强的语义,并且消息没有允许重复数据消除的主键。

原文引用:So effectively Kafka guarantees at-least-once delivery by default and allows the user to implement at most once delivery by disabling retries on the producer and committing its offset prior to processing a batch of messages. Exactly-once delivery requires co-operation with the destination storage system but Kafka provides the offset which makes implementing this straight-forward.

    Kafka 默认情况下有效地保证了“至少一次”传递,并允许用户通过禁止生产者重试和处理一批消息前提交它的偏移量来实现“最多一次”传递。而“正好一次”传递需要与目标存储系统合作,但 Kafka 提供了偏移量,所以实现这个很简单。

这篇关于Kafka 设计之消息传递保障的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/786614

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

搭建Kafka+zookeeper集群调度

前言 硬件环境 172.18.0.5        kafkazk1        Kafka+zookeeper                Kafka Broker集群 172.18.0.6        kafkazk2        Kafka+zookeeper                Kafka Broker集群 172.18.0.7        kafkazk3

怎么让1台电脑共享给7人同时流畅设计

在当今的创意设计与数字内容生产领域,图形工作站以其强大的计算能力、专业的图形处理能力和稳定的系统性能,成为了众多设计师、动画师、视频编辑师等创意工作者的必备工具。 设计团队面临资源有限,比如只有一台高性能电脑时,如何高效地让七人同时流畅地进行设计工作,便成为了一个亟待解决的问题。 一、硬件升级与配置 1.高性能处理器(CPU):选择多核、高线程的处理器,例如Intel的至强系列或AMD的Ry

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机

SprinBoot+Vue网络商城海鲜市场的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍:CSDN认证博客专家,CSDN平台Java领域优质创作者,全网30w+

单片机毕业设计基于单片机的智能门禁系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍程序代码部分参考 设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订

Spring的设计⽬标——《Spring技术内幕》

读《Spring技术内幕》第二版,计文柯著。 如果我们要简要地描述Spring的设计⽬标,可以这么说,Spring为开发者提供的是⼀个⼀站式的轻量级应⽤开发框架(平台)。 作为平台,Spring抽象了我们在 许多应⽤开发中遇到的共性问题;同时,作为⼀个轻量级的应⽤开发框架,Spring和传统的J2EE开发相⽐,有其⾃⾝的特点。 通过这些⾃⾝的特点,Spring充分体现了它的设计理念:在

开题报告中的研究方法设计:AI能帮你做什么?

AIPaperGPT,论文写作神器~ https://www.aipapergpt.com/ 大家都准备开题报告了吗?研究方法部分是不是已经让你头疼到抓狂? 别急,这可是大多数人都会遇到的难题!尤其是研究方法设计这一块,选定性还是定量,怎么搞才能符合老师的要求? 每次到这儿,头脑一片空白。 好消息是,现在AI工具火得一塌糊涂,比如ChatGPT,居然能帮你在研究方法这块儿上出点主意。是不

创业者该如何设计公司的股权架构

本文来自七八点联合IT橘子和车库咖啡的一系列关于设计公司股权结构的讲座。 主讲人何德文: 在公司发展的不同阶段,创业者都会面临公司股权架构设计问题: 1.合伙人合伙创业第一天,就会面临股权架构设计问题(合伙人股权设计); 2.公司早期要引入天使资金,会面临股权架构设计问题(天使融资); 3.公司有三五十号人,要激励中层管理与重要技术人员和公司长期走下去,会面临股权架构设计问题(员工股权激

分布式文件系统设计

分布式文件系统是分布式领域的一个基础应用,其中最著名的毫无疑问是 HDFS/GFS。如今该领域已经趋向于成熟,但了解它的设计要点和思想,对我们将来面临类似场景 / 问题时,具有借鉴意义。并且,分布式文件系统并非只有 HDFS/GFS 这一种形态,在它之外,还有其他形态各异、各有千秋的产品形态,对它们的了解,也对扩展我们的视野有所俾益。本文试图分析和思考,在分布式文件系统领域,我们要解决哪些问题、有