写在前面
上篇说到了kafka由于重复发送消息导致消息重复的问题。那不重发就不会重复了,的确是这样的,但这样也会带来一个问题。producer只发送一次,那消息丢失了怎莫办?
一.消息丢失
说到消息丢失,就不得不说到一个参数ACK。该参数有三个值,分别是0,1和all(或者-1)。这三个值关系到我们的消息是否真正写入成功到kafka。
使用过kafka的小伙伴都知道有leader和follower角色,follower负责同步leader的数据,以实现高可用消息不丢失。而ACK参数就是来控制消息是否真正写入成功的。
2.1 ack参数详解
-
0
如果设置为0,表示生产者不会等待broker对消息的确认。producer发出去就会得到相应,不清楚是否发到了broker上,同时重试配置也不会生效。 -
1
消息只需要写到leader,然后就响应客户端,不等follower确认。这样是有风险的,假如leader写入了消息,follower没来得及同步数据,此时leader挂了,那数据就没了。 -
all
all的意思是说producer向leader写入了数据,同时follower同步了数据,才向producer返回响应说数据成功写入kafka。这里面有个ISR问题,后期我们会详说。可以说all是kafka的最强可靠性保证。
相信大家看完,就知道了ack问题。
2.2 ISR
在数据同步这一块,有个ISR的概念,意思是同步中的副本。
所有与leader副本保持一定程度同步的副本(包括Leader)组成ISR(In-Sync Replicas),一定程度表示允许有延迟。
这里说明一下kafka的leader副本是可以选举的,当leader副本挂掉了,broker会从其他副本长选举出新的副本。假如允许从落后太多的副本中选举,也就是非ISR副本(OSR)中选举,那数据肯定会丢失,OSR就是落后太多数据的一群。
默认不允许如上操作,但为了快速恢复集群的可用性,也就是设置
unclean.leader.election.enable=true就会造成数据丢失。
2.3 min.insync.replicas
该参数表示副本的最小数目,假如只有一个,那该副本宕机了,那数据也就丢失了。
所以,min.insync.replicas一半设为>1,和ack=-1配合使用。