Producer发送数据丢失、重复、乱序原因及解决方案是什么

这篇文章给大家介绍Producer发送数据丢失、重复、乱序原因及解决方案是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

创新互联公司联系电话:18980820575,为您提供成都网站建设网页设计及定制高端网站建设服务,创新互联公司网页制作领域十年,包括服务器租用等多个行业拥有多年的网站制作经验,选择创新互联公司,为企业保驾护航。

    生产环境对于生产者来说,Kafka集群发送消息经常会遇到消息丢失、重复、乱序等问题,下面我们来讲解一下出现这些问题的原因及解决方案。

1.我们知道Kafka为保障数据的可靠性,采用了多副本的存储机制

    假设一个Topic拆分为了3个Partition,分别是PartitionA,PartitonB,PartitionC,此时每个Partition都有2个副本。比如PartitionA有一个副本是leader,另外一个副本是follower,leader和follower两个副本是分布在不同机器上的。

    一般生产环境我们都会指定Topic的数据有3个副本,即使一台broker挂掉以后,数据也不会彻底丢失,因为其他broker还存在另外的副本数据。

2.副本数据是如何进行同步的呢?

    对于多个副本的topic来说,只有分区leader提供读写服务的,follower只是不停的尝试从leader拉取最新的数据到本地,不提供读写服务,跟leader数据保持同步的数据有哪些呢?就是通过ISRl来管理的。

    ISR全称是“In-Sync Replicas”,就是能跟首领副本基本保持一致的跟随副本,如果同步的速度太慢的话,就会被踢出ISR副本。

3.说一下Kafka的Producer端消息传递语义,由参数"acks"控制,分三种:

a.acks=all

    意味着当Producer发送消息时,leader接收到消息之后,还必须要求ISR列表里跟leader保持同步的那些follower都要把消息同步过去,才能认为这条消息是写入成功了,这种效率最低,但是可靠性最高。

b.acks=1:

    意味着当Producer发送消息时,leader接收到消息而且写入本地磁盘了,就认为成功了,不管他其他的follower有没有同步过去这条消息了,acks默认值为1。

c.acks=0:

    意味着当Producer发送消息时,producer发送一次就不再发送了,不管是否发送成功,这种情况下没有任何的确认,可能存在消息的丢失;这种效率最高,但是可靠性最低。

4.Producer端引起数据丢失、重复、乱序的原因及解决方案

1).Producer发送数据分为同步、异步两种模式,由参数producer.type控制,一般生产采用异步模式批量发送,提高Kafka系统的吞吐率。

a同步模式 producer.type = sync:

    当acks=0,不进行消息接收的确认,那么当网络异常时,就会造成数据丢失,一般生产不建议设置为0;

    当acks=1,在只有leader接收成功并发送ack确认后,leader宕机,副本没有同步完成,也会造成数据丢失;

    上面两种数据丢失,我们可以设置acks=all,保证produce 写入所有副本算成功,效率比较低。

 producer.type = sync  request.required.acks=all

b.异步模式 producer.type = async:

    异步模式下的有个buffer,通过buffer来进行控制数据的发送,有两个值来进行控制,时间阈值与消息的数量阈值,如果buffer满了数据还没有发送出去,如果设置的是立即清理模式,风险很大,容易造成数据丢失。一般设置为阻塞模式:queue.enqueue.timeout.ms = -1表示后台消息queue积压到上限后将一直阻塞,直到queue空间释放;

producer.type = asyncrequest.required.acks=1queue.buffering.max.ms=6000queue.buffering.max.messages=10000queue.enqueue.timeout.ms = -1batch.num.messages=500

3).acks = all时,数据发送到 leader 后 ,数据发送到 leader 后 ,部分 ISR 的副本同步,leader 此时挂掉。比如 follower1 和 follower2 都有可能变成新的 leader, producer 端会得到返回异常,producer 端会重新发送数据,可能会造成数据重复,这种可通过幂等性和事务解决,后续会讲;

4).acks=all时,当isr列表为空,如果unclean.leader.election.enable为true,则会选择其他存活的副本作为新的leader,也会存在消息丢失的问题

可通过设置参数:

unclean.leader.election.enable=false

    这个参数在0.11.0之前其默认值为true,而之后的版本其默认值为false。意思是,在leader选举时是否在没有活着的ISR副本时从OSR中的最早follower选举,如果为true可能会造成数据的丢失;

5).异步发送消息时,有两条数据数据准备发送到相同的Partition,第一条消息写入失败,第二条消息写入失败,经过重试后第一批次写入成功,这时就会造成发送数据的乱序,这种情况我们可以通过设置参数进行限制:

参数:max.in.flight.requests.per.connection

    表示请求队列大小,默认5,请求队列中存放的是在发送途中的请求,包括:正在发送的请求和已经发送的但还没有接收到response的请求;请求队列满了,发送消息将会发生阻塞。也就是发往同一个node的最大未响应请求。设置此值是1,表示kafka broker在响应请求之前client不能再向同一个broker发送请求,这样便可以避免消息乱序。

    通过4的分析发现kafka在两端的默认配置都是at least once,可能重复,通过配置也不能做到exactly once,好像kafka的消息一定会丢失或者重复,在kafka 0.11.0.0版本之后,开始引入了幂等性和事务机制来解决上述问题。


扩充知识点:

1.Kafka发送数据过快,导致服务器网卡流量暴增。或磁盘过忙,出现丢包,造成。这时候我们采取以下措施:

     a.首先,对kafka进行限速;

     b.其次启用重试机制,使重试间隔变长;

     c.Kafka设置ack=all,即需要处于ISR(副本列表)的分区都确认,才算发送成功。

关于Producer发送数据丢失、重复、乱序原因及解决方案是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。


标题名称:Producer发送数据丢失、重复、乱序原因及解决方案是什么
转载注明:http://myzitong.com/article/ppieoe.html