ACK
在 Kafka 中,ack(Acknowledgment)机制是指用于确认生产者发送的消息已经被成功写入到 Kafka 分区中的一种机制。生产者可以通过 ack 参数来控制这个机制,以便根据自己的需求进行设置。
ACK应答级别
0:生产者发送过来的数据,不需要等数据落盘应答。
1:生产者发送过来的数据,Leader 收到数据后应答。
-1(all):生产者发送过来的数据,Leader+和 isr 队列里面的所有节点收齐数据后应答。默认值是-1,-1 和 all 是等价的。
Leader收到数据,所有Follower都开始同步数据,但有一个Follower,因为某种故障,迟迟不能与Leader进行同步,那这个问题怎么解决呢?
Leader维护了一个动态的in-sync replica set(ISR),意为和Leader保持同步的Follower+Leader集合(leader:0,isr:0,1,2)。
如果Follower长时间未向Leader发送通信请求或同步数据,则该Follower将被踢出ISR。该时间阈值由replica.lag.time.max.ms参数设定,默认30s。例如2超时,(leader:0, isr:0,1)。
这样就不用等长期联系不上或者已经故障的节点。
如果分区副本设置为1个,或 者ISR里应答的最小副本数量( min.insync.replicas 默认为1)设置为1,和ack=1的效果是一样的,仍然有丢数的风险(leader:0,isr:0)。
数据完全可靠条件 = ACK级别设置为-1 + 分区副本大于等于2 + ISR里应答的最小副本数量大于等于2
可靠性总结:
acks=0,生产者发送过来数据就不管了,可靠性差,效率高;
acks=1,生产者发送过来数据Leader应答,可靠性中等,效率中等;
acks=-1,生产者发送过来数据Leader和ISR队列里面所有Follwer应答,可靠性高,效率低;
注:在生产环境中,acks=0很少使用;acks=1,一般用于传输普通日志,允许丢个别数据;acks=-1,一般用于传输和钱相关的数据,对可靠性要求比较高的场景。
acks = all 数据重复分析
当 Kafka 生产者的 acks 参数设置为 all 时,只有在所有的 ISR(In-Sync Replicas,同步副本)都确认接收并成功写入数据后,生产者才会收到成功的响应。但是,由于网络等原因,可能会出现某些 ISR 没有及时接收到数据的情况。此时,生产者会重发数据,以保证所有的 ISR 都能接收到数据。
在 Kafka 中,当生产者发送一条消息到分区时,分区中的所有 ISR 都会尝试接收该消息并写入到本地磁盘上。如果某些 ISR 没有接收到该消息,或者该消息在某些 ISR 上写入失败,那么这些 ISR 就会发出请求要求重新发送该消息。生产者会根据请求重新发送消息,确保所有的 ISR 都能接收到该消息并将其写入到本地磁盘上。