-
数据复制:为了保证数据的高可用性,Kafka 需要将数据复制到不同的 Broker 节点上。这是通过多副本机制实现的,每个 TopicPartition 都有一个 Leader 和多个 Follower。
-
写入确认:在数据被复制到其他 Broker 节点之前,默认情况下,Broker 不会向生产者反馈数据写入成功。这意味着生产者可能需要等待数据被复制到所有同步副本(ISR)后才能得到确认。
-
炼狱(Purgatory):为了提高复制数据的效率,Leader 节点会将需要复制的数据生成一个请求对象,并存储在 map 结构的炼狱中。炼狱是一种特殊的数据结构,用于存储尚未完成的复制请求。
-
Follower 的 I/O 线程:Follower 副本的 I/O 线程负责从 Leader 接收数据,并将其复制到自己的 PageCache 中。这个过程是异步的,并且通常在后台进行。
-
复制完成:一旦数据被完全复制到其他 Broker 节点的 PageCache 中,Follower 会向 Leader 发送复制完成的确认。
-
响应生产者:收到所有 Follower 的复制确认后,Broker 会将请求对象从炼狱中取出,生成一个响应对象,并将其放在响应队列中。这样,生产者就可以从响应队列中获取到写入成功的反馈。
-
生产者配置:生产者可以通过设置 acks 参数来控制何时收到写入确认。例如,acks=0 表示不需要 Leader 的确认,acks=1 表示只需要 Leader 的确认,而 acks=all 表示需要所有同步副本的确认。
-
数据的持久性:尽管 Kafka 允许异步刷盘,但它仍然提供了持久性保证,通过多副本机制确保数据在多个节点上可用,从而在发生故障时可以快速恢复。