如何保证Kafka中的数据有序性

  

  • kafka在生产者发送完一个消息之后,要求broker在规定的时间内Ack应答;如果没有在规定时间内ack;生产者会尝试n次重新发送消息。
  • acks=1 (默认)Leader会将Record写在其本地日志中;但不会等待所有Follower的完全确认的情况下做出响应,这种情况下,如果Leader在确认记录后立即失败,在Follower复制记录之前失败,则记录会丢失
  • acks=0 生产者不等待服务器确认,将记录加载到缓冲区即视为发送;这种情况不能保证服务器已收到记录
  • acks=all 表示Leader将等待全套同步副本确认记录。保证至少一个同步副本仍处于活动状态,记录不会丢失。-- 等效于acks= -1。


  Kafka中的数据数据有序从架构上来看只能是分区内的有序,打乱这种顺序的原因是依旧是集群常见的IO异常,即NetworkClient网络对象发起的请求可能失败,造成broker获取的数据和原数据分区不一致的情况。

  在1.x版本之前,保证单分区内有序,只能设置max.in.flight.requests.per.connection=1,即每个broker节点只能缓存一个请求,每个请求成功后,才继续发送下一个数据记录的请求,这样明显的效率低下。

 

  在0.11版本,引入了一项重大的特性:幂等性和事务,来保证数据的精确一次。

  精确一次:要求数据既不能重复也不能丢失(事务+幂等性+至少一次(ack=-1 + 分区副本数>=2 + ISR最小副本数量>=2)).

  幂等性:不论Producer向Broker发送多少次重复数据,Broker端都只会持久化一条,保证了不重复。原理是给消息添加<PID,Partition,SeqNumber>.

  事务:存储在Broker中的元数据,Broker中的两大元数据主题之一(即:事务主题和cosumer_offset主题)

 

  开启幂等性:Kafka服务端会缓存Producer发来的最近5个request的幂等性元数据,每次将Broker内存中的元数据落盘前,都会和缓存中的元数据对比,如果不是连续的seqNumber数据无法落盘,也就无法正确返回ack,request将无法得到响应而阻塞。

  同时,因为服务器只会缓存Producer发来的最近5个request的幂等性元数据,故而服务器最大能够处理排序的消息也是五个,sender线程保证顺序能发送到Broker中的单分区数据也必须小于五个,故而max.in.flight.requests.per.connection=[1,5].

 

总结:

  保证Kafka中的数据单分区有序:

  开启幂等性:在prudocer的配置对象中,添加参数enable.idempotence,参数值默认为true,设置为false就关闭了。

  配置max.in.flight.requests.per.connection=[1,5].

posted @   Avery_rainys  阅读(1085)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示