消息路由策略
- productor 选取 partition 分区的策略(broker contorller 将当前 topic 所有的 partition leader 返回给 productor)
- 直接指定了 partition,则直接写入到 partition
- 没有指定 paritition,但是指定了 key,通过 key 的 hash 值与 partition 数量取模,该取模的结果就是要选出的 partiton 索引
- 若 partition 和 key 都没有指定,轮询算法选一个
消息写入算法
- 生成者 向 broker 提交连接请求,连接上的任意 broker 都会向其发送 broker controller 的通信 url
- 生成者 指定要消费的 topic,broker controller 接受到请求后,从 zk 中查找指定 topic 的所有 partition 的 leader。返回给生成者
- 生产者 接受到 leader 的列表后,根据消息路由策略选择要发送的 partition leader。将消息发出
- leader 将消息写入到 本地 log。并通知 isr 中的 follower
- isr 中的 followers 从 leader 同步信息后,向 leader 响应 ack
- leader 收到所有的 ack 后,增加 HW, 标识消费者可以消费到该位置了。
消息写入过程存在哪些问题?
- leader 接受到消息后,宕机怎么办,leader 可能因为网络问题,接不到消息?
- partition leader 选举的过程中 ISR 列表中没有从节点怎么办?
- leader 没有收到所有的 ack 的时候,宕机了。会存在问题?
- 生产者生产消息后,broker 没有给返回 ack,超时后,重新提交消息问题
1. 消息发送可靠性机制
- 通过配置可靠性级别 ack 参数的值进行设置
- 0 值,异步发送,生产者 发送消息后,不需要 kafka 反馈成功 ack。效果高。可靠性低。有可能存在消息丢失
- 1 值,同步发送,partition leader 收到消息后,马上发送成长 ack。存在的问题 是 当 leader 收到消息后,还没有向 follower 同步,leader 挂了。原来写入到 leader 中的消息丢失了。
- -1 值,同步发送,当所有 partition 的副本都同步完消息后,才能向生产者发送 ack。如果超时后,生产者会自动重发。很少出现消息丢失。存在重复消息接受情况。kafka 运行为消息生成唯一标识。允许用户自定义去重。
2. partition leader 的选举范围
- ISR 列表中没其他副本的时候。可以通过 参数 unclean.leader.election.enable 取值 设置 leader 选举
- false 标识有副本活过来 才进行选举,该策略可靠性有保证。但是可用性低
- true 标识从任何没有宕机的 follower 中选一个,可能存在大量的消息丢失。可靠性没有保障
3. HW 截断机制
leader 收到消息后,ISR 中其它 Follower 正在进行同步过程中,还未同步完毕。leader 宕机。会出现 paritition 中的 leader 和 follower 的数据不一致
。使用截断。当 leader 恢复后,将其从 leo 回退到 其宕机时候的 HW。然后再与新的 leader 进行数据同步。
(HW 截断机制可能会引发消息的丢失)