@Alpacadh
2022-09-18T17:19:18.000000Z
字数 1647
阅读 219
kafka
Producer 发送消息到 broker 时,会根据分区算法选择将其存储到哪一个 Partition。其路由机制为:
1)指定了 Partition,则直接使用;
2)未指定 Partition 但指定 key,通过对 key 的 value 进行 hash 选出一个 Partition;
3)Partition 和 key 均未指定,就使用轮询选出一个 Partition。
1)Producer 先从 Zookeeper 的 /brokers/.../state 节点找到该 Partition 的 Leader;
2)Producer 将消息发送给该 Leader;
3)Leader 将消息写入本地 log;
4)Followers 从 Leader pull 消息,写入本地 log 后向 Leader 发送 ACK;
5)Leader 收到 ISR 中所有 replica 的 ACK 后,增加 HW(high watermark,最后 commit 的 offset)并向 Producer 发送 ACK。
Kafka 生产者 ProducerConfig 中的 ACK 配置一般常设置三种值:
Kafka 消息有以下三种可能的 delivery guarantee:
Producer 到 Broker 的 delivery guarantee semantic 非常直接。当producer向broker发送消息时,一旦这条消息被commit,由于replication的存在,它就不会丢。但是如果producer发送数据给broker后,遇到的网络问题而造成通信中断,那producer就无法判断该条消息是否已经commit。这一点有点像向一个自动生成primary key的数据库表中插入数据。虽然Kafka无法确定网络故障期间发生了什么,但是producer可以生成一种类似于primary key的东西,发生故障时幂等性的retry多次,这样就做到了Exactly one。所以目前默认情况下一条消息从producer和broker是确保了At least once,但可通过设置producer异步发送实现At most once。