赞
踩
首先这个acks参数,属于KafkaProducer,也就是在生产者客户端里设置的,你往kafka写数据的时候,可以来设置这个acks参数。
这个参数有三种常见的值可设置,分别是:0、1 和 all。
我的KafkaProducer在客户端,只要把消息发送出去,不管那条数据有没有发送出去,哪怕Partition Leader没有写入磁盘,也不管他了,直接认为这个消息发送成功。
如果采用这种设置,你必须注意的一点是,可能你发送出去的消息还在半路。结果,Partition Leader所在Broker直接挂了,结果你的客户端还认为消息发送成功了,此时就会导致这条消息就丢失了。
只要Partition Leader接收到消息且写入本地磁盘,就认为成功,不管他其他的Follower有没有同步过去这条消息。
这种设置其实是kafka默认的设置,大家请注意,划重点!这是默认的设置
也就是说,默认情况下,你要是不管acks这个参数,只要Partition Leader写成功就算成功。
但是这里有一个问题,万一Partition Leader刚刚接收到消息,Follower还没来得及同步过去,结果Leader所在的broker宕机了,此时也会导致这条消息丢失,因为人家客户端已经认为发送成功了。
Partition Leader接收到消息之后,还必须要求ISR列表里跟Leader保持同步的那些Follower都要把消息同步过去,才认为这条消息是写入成功的。
如果说Partition Leader刚接收到了消息,但是结果Follower没有收到消息,此时Leader宕机了,那么客户端会感知到这个消息没发送成功,他会重试再次发送消息过去。
此时可能Partition 2的Follower变成Leader了,此时ISR列表里只有最新的这个Follower转变成的Leader了,那么只要这个新的Leader接收消息就算成功了。
acks=all 就能保证数据一定不会丢失了吗?
不一定,如果你的Partition只有一个副本,也就是一个Leader,任何Follower都没有,你认为acks=all有用吗?
当然没用了,因为ISR里就一个Leader,他接收完消息后宕机,也会导致数据丢失。
所以,这个acks=all,必须跟ISR列表里至少有2个以上的副本配合使用,起码是有一个Leader和一个Follower才可以。
这样才能保证说写一条数据过去,一定是2个以上的副本都收到了才算是成功,此时任何一个副本宕机,也不会导致数据丢失。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。