kafka数据可靠性与一致性

Kafka是一款高性能、高可用的分布式发布订阅消息系统。 从 0.10 版本开始,Kafka Streams java库提供了流处理数据的基本操作,从此Kafka 的标语已经改为一个分布式流平台。保证Kafka高可用模型依靠的是副本机制,副本机制保障机器宕机不会发生数据丢失问题。那么如何解决写多份带来一致性问题呢?如何解决一致性问题又会带来性能问题?

微信图片_20211124195045.png

ISR 复制机制

ISR (In-Sync Replicas)是Leader在Zookeeper(/brokers/topics/[topic]/partitions/[partition]/state)目录中动态维护基本保持同步的Replica列表,该列表中保存的是与Leader副本保持消息同步的所有副本对应的节点id。如果一个Follower宕机或者其落后情况超过任意参数replica.lag.time.max.ms(延迟时间)、replica.lag.max.messages(延迟条数,Kafka 0.10.x版本后移除)设置阈值,则该Follower副本节点将从ISR列表中剔除并存入OSR(Outof-Sync Replicas)列表。

ISR冗余备份机制核心逻辑围绕HW值、LEO值展开。

LEO(log end offset)日志末端偏移量,记录了该副本对象底层日志文件中下一条消息的位移值。

HW(highwatermark),高水印值,任何一个副本对象的HW值一定不大于其LEO值,而小于或等于HW值的所有消息被认为是“已提交的”或“已备份的”。consumer只能消费已提交的消息,HW之后的数据对consumer不可见。

u=1743374214,2048573772&fm=173&app=25&f=JPEG.jpg

数据同步过程如下:

Follower向Leader发送fetch请求(此过程类似于普通Customer,区别在于内部broker的读取请求,没有HW的限制)。

Leader接收到Follwer fetch操作后根据fetch请求中Postion从自身log中获取相应数据,并根据fetch请求中Postion更新leader中存储的follower LEO。通过follower LEO读取存在于ISR列表中副本的LEO(包括leader自己的LEO)值,并选择最小的LEO值作为HW值。

Follower接收到leader的数据响应后,开始向底层log写数据,每当新写入一条消息,其LEO值就会加1,写完数据后,通过比较当前LEO值与FETCH响应中leader的HW值,取两者的小者作为新的HW值。

由此可见,Kafka复制机制既不是完全的同步复制,也不是单纯的异步复制,Kafka通过 ISR复制机制在保障数据一致性情况下又可提供高吞吐量。

数据一致性保证

  • request.required.acks:该参数在producer向leader发送数据时设置。

0:producer无需等待来自broker的确认而继续发送下一批消息。这种情况下数据传输效率最高,但是数据可靠性确是最低的。

1(默认):producer在ISR中的leader已成功收到数据并得到确认。如果leader宕机了,则会丢失数据。

-1:producer需要等待ISR中的所有follower都确认接收到数据后才算一次发送完成,可靠性最高。但是这样也不能保证数据不丢失,比如当ISR中只剩下一个leader时,这样就变成了acks=1的情况。

min.insync.replicas:该参数在broker或者topic层面进行设置,设定ISR中的最小副本数是多少,默认值为1,当且仅当request.required.acks参数设置为-1时,此参数才生效。如果ISR中的副本数少于min.insync.replicas配置的数量时,客户端会返回异常:org.apache.kafka.common.errors.NotEnoughReplicasExceptoin: Messages are rejected since there are fewer in-sync replicas than required。

  • unclean.leader.election.enable:

true:默认值,所有replica都有成为leader的可能。

false:只有在ISR中存在的replica才有成为leader的可能。

要保证数据写入到Kafka是安全的,高可靠的,需要如下的配置:

topic的配置:replication.factor>=3,即副本数至少是3个;

2<=min.insync.replicas<=replication.factor

broker的配置:leader的选举条件unclean.leader.election.enable=false

producer的配置:request.required.acks=-1(all),producer.type=sync(同步)

Guess you like

Origin juejin.im/post/7034111562243637285