前言
之前的博客里说了,Kafka的消息同步是一种ISR机制,本质上是“完全同步”的一种优化。
都在说,消息被ISR中所有副本都写入才算写入成功。但是这样未免定的太死板了,所以,Kafka给出了我们选择。
这个选择就是ack机制
生产者参数
request.required.acks 是producer可以指定的参数
ack = 1 (默认)
leader写入成功,producer就能收到成功响应(这和同步不同步没关系,你就当只有leader,没有follower就行)
ack = 0
producer只管发,不等待服务器响应,爱成功不成功。(吞吐量最高)
ack = -1 / ack = all
producer 需要等待 ISR 中的所有replica都成功写入,才能够收到来自服务端的成功响应。
这才是ISR的正确应用场景,可靠性最高
ISR的最坏情况
排除所有replica全部故障,ISR的最坏情况就是ISR中只剩leader自己一个了。
退化成 ack = 1的情况了,甚至还不如ack=1。
ack=1,说的是producer不等服务端完全同步完ISR,只要leader写入成功就行了,但是可没说不进行同步了。
该有的同步过程还是会进行的,但凡能同步,Kafka肯定会同步的,而ack=1的最坏情况,也是ISR中只剩下leader了。
换句话说,producer为了提高吞吐量,没等ISR全部同步,但是心里还是希望进口同步完成的。
而这种leader孤家寡人的最坏情况,书上说“退化成ack=1",笔者认为不足以说明问题的严重性。
ISR的最坏情况,会使ack=-1 退化成 ack=1时的最坏情况,完全背离我们设置-1的初衷(因为铁定是同步不了了)。
与其他参数的配合使用
min.insync.replicas = n(broker的配置)
如果生产者acks=all,而在发送消息时,ISR中的replica数量没有达到n,Broker不能处理这条消息,需要直接给生产者报错。
所以只要 min.insync.replicas >= 2,就能避免由ISR的最坏情况出现导致的丢消息。