# 集群成员关系
每个 broker 拥有一个 ID,加入或退出集群时会在 zk /brokers/ids 路径上注册或删除自己的 ID。
# 控制器
broker 启动时会在 zk /controller 路径上注册成为控制器,第一个成功注册的 breker 会成为控制器,负责分区首领的选举。
# 复制
副本类型:
- 首领副本
- 跟随者副本
# 处理请求
broker 大部分工作是处理客户端、分区副本和控制器发送给分区首领的请求。
处理请求的内部流程:
# 元数据请求
# 生产请求
- 权限验证
- acks 是否有效
- 根据 acks 检查是否写入
# 获取请求
与生产请求类似,要根据元数据确保请求路由正确,然后使用零复制技术向客户端发送消息,只能发送高位线的数据。
# 其他请求
很多。
# 物理存储
基本存储单元是分区。
# 分区分配
分配原则:
- 在 broker 间平均分布
- 确保每个分区的每个副本在分布在不同的 broker 上
- 尽可能把每个分区的副本分配到不同机架的 broker 上
# 文件管理
分区分成若干个片段,每个片段默认包含 1GB 或一周的数据。
当前正在写入的片段叫做活跃片段。
# 文件格式
# 索引
偏移量的索引,方便消费者指定偏移量进行消费。
# 清理
清理主题中超过时效的数据,相同键值的消息会清理旧的消息。
# 原理
日志片段分为:
- 干净的部分,上次清理过的
- 污浊的部分,上次清理后写入的
通过 map (key 为消息键的散列值,value 为消息的偏移量) 保存污浊的部分,然后从旧消息开始读取,如果 map 中不存在,说明是最新的,就将消息复制到替换片段上,如果存在,说明不是最新的,就忽略消息,最后把替换片段与原始片段交换。
# 被删除的事件
删除某个键的消息,可发送一个墓碑消息(值为 null),消费者消费到就可知其意,kafka 也会进行清理。
# 何时清理主题
delete 策略不会删除活跃片段,compact 策略也不会清理当前片段。
早的版本在主题数量达到 50% 时进行清理,未来版本使用宽限期。