irpas技术客

[Kafka] Kafka如何保证消息不丢失、不重复?_Cloudeeeee_kafka防止数据丢失与不重复

irpas 4908

[Kafka] Kafka如何保证消息不丢失、不重复 Kafka基本架构Kafka如何保证消息不丢失、不重复Kafka消息的丢失和重复可能会发生在哪里?Kafka如何保证`生产者端`的消息不丢失、不重复?生产者端`丢失数据`的情况分析生产者端`丢失数据`的解决办法生产者端`重复发送数据`的情况分析及解决办法消费者端`丢失数据`的情况分析及解决办法消费者端`重复消费数据`的情况分析及解决办法

Kafka基本架构

生产者Producer :生产信息;消费者Consumer :订阅主题、消费信息;代理Broker : 可以看作是一个独立的 Kafka 实例。多个 Kafka Broker 组成一个卡夫卡集群 Kafka Cluster;主题topic:可以理解为一个队列, 生产者和消费者面向的都是一个 topic, Producer 将消息发送到特定的主题,Consumer 通过订阅特定的主题来消费消息;分区partition: 为了实现扩展性,一个非常大的 topic 可以分布到多个 broker(即服务器)上,一个 topic 可以分为多个 partition,每个 partition 是一个有序的队列。副本Replica: :副本,为保证集群中的某个节点发生故障时,该节点上的 partition 数据不丢失,且 kafka 仍然能够继续工作,kafka 提供了副本机制,一个 topic 的每个分区都有若干个副本,一个 leader 和若干个 follower。leader :每个分区多个副本的“主”,生产者发送数据的对象,以及消费者消费数据的对象都是 leader。follower :每个分区多个副本中的“从”,实时从 leader 中同步数据,保持和 leader 数据的同步。leader 发生故障时,某个 follower 会成为新的 follower。 Kafka如何保证消息不丢失、不重复 Kafka消息的丢失和重复可能会发生在哪里?

根据以上的Kafka架构图,我们推测一下,消息丢失可能会发生在哪里?

生产者丢失数据

消费者丢失数据

那么消息重复消费可能会发生在哪里?

同样也是在消费者端和生产者端,即:

生产者重复发送数据

消费者重复消费数据

如何保证消息的有序?

同步发送模式:发出消息后,必须等待阻塞队列收到通知后,才发送下一条消息;同步发送模式可以保证消息不丢失、又能保证消息的有序性。

异步发送模式:生产者一直向缓冲区写消息,然后一起写到队列中;好处是吞吐量大,性能高。

Kafka如何保证生产者端的消息不丢失、不重复? 生产者端丢失数据的情况分析

生产者端使用同步发送模式,有三种状态保证消息被安全生产,即配置acks参数(默认为1):

● 1:集群的leader节点收到消息后,就可以发回成功写入的通知

● 0:生产者在成功写入消息之前不会等待来着服务器的任何响应,即不在乎消息是否丢失了

● 3:集群中的所有节点都收到消息时,才发回成功写入的通知,这种方式最可靠,但是性能最低

因此,当使用参数1且leader节点在写入参数时挂掉了,数据就会丢失。

使用异步模式时,当缓冲区满了,如果配置为0,则还没收到确认的情况下,缓冲区一满就会清空缓冲区中的消息,数据就丢失了

生产者端丢失数据的解决办法

在同步模式下,将发送消息的确认机制设置为-1,使得所有节点确认后再发送下一条数据即可

在异步模式下,如果消息发送出去了,但还没有收到确定的时候,在配置文件中设置成不限制阻塞超时的时间,即让生产者一直保持等待,也可以保证数据不丢失

生产者端重复发送数据的情况分析及解决办法

重复发送数据,不用管,在消费者端建立去重表即可。


消费者端丢失数据的情况分析及解决办法

如果消息在处理完成前就提交了offset,就有可能造成数据的丢失。解决办法是在后台提交位移前确保消息已经被正常处理了,然后手动提交offset(调用**commitSync()**函数)。

附注:offset(偏移量)是什么? Kafka中每一个分区partition都由一系列有序的、不可变的消息组成,这些消息被连续地追加到partition中,partition中的每个消息都有一个连续的序号,用于唯一标识一条消息,offset就记录着下一条将要发送给消费者的消息的序号,offset从语义上来看有两种:

Current Offset

Committed Offset

Current Offset保存在消费者的客户端中,它表示希望收到的下一条消息的序号,Offset保证每次消费者消费信息时,都能收到正确位置的消息。

Committed Offset保存在broker上,它表示消费者已经确认消费过的消息的序号,这个确认需要消费者调用commitSync()函数,如果调用了这个函数,Commit Offset会被更新为Current Offset的值,如果没有调用这个函数,那么它就不会改变,依然是0。它保证新的消费者能够从正确的位置开始消费信息,从而避免重复消费。

消费者端重复消费数据的情况分析及解决办法

在消费者端建立去重表即可保证消息只会被消费一次。


附注:Kafka的消息是消费完就消失的吗? kafka中的数据的删除和消费者是否消费无关,数据的删除只与kafka broker中 的数据保存时间(log.retention.hours=48,数据最大保存48小时)和数据最大保存内存(log.retention.bytes=1073741824,数据最大保存1G)有关。


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #kafka防止数据丢失与不重复 #Kafka #生产信息消费者Consumer #可以看作是一个独立的