# 集群成员关系

每个 broker 拥有一个 ID,加入或退出集群时会在 zk /brokers/ids 路径上注册或删除自己的 ID。

# 控制器

broker 启动时会在 zk /controller 路径上注册成为控制器,第一个成功注册的 breker 会成为控制器,负责分区首领的选举。

# 复制

副本类型:

  • 首领副本
  • 跟随者副本

# 处理请求

broker 大部分工作是处理客户端、分区副本和控制器发送给分区首领的请求。

处理请求的内部流程:

# 元数据请求

# 生产请求

  1. 权限验证
  2. acks 是否有效
  3. 根据 acks 检查是否写入

# 获取请求

与生产请求类似,要根据元数据确保请求路由正确,然后使用零复制技术向客户端发送消息,只能发送高位线的数据。

# 其他请求

很多。

# 物理存储

基本存储单元是分区。

# 分区分配

分配原则:

  • 在 broker 间平均分布
  • 确保每个分区的每个副本在分布在不同的 broker 上
  • 尽可能把每个分区的副本分配到不同机架的 broker 上

# 文件管理

分区分成若干个片段,每个片段默认包含 1GB 或一周的数据。
当前正在写入的片段叫做活跃片段。

# 文件格式

# 索引

偏移量的索引,方便消费者指定偏移量进行消费。

# 清理

清理主题中超过时效的数据,相同键值的消息会清理旧的消息。

# 原理

日志片段分为:

  • 干净的部分,上次清理过的
  • 污浊的部分,上次清理后写入的

通过 map (key 为消息键的散列值,value 为消息的偏移量) 保存污浊的部分,然后从旧消息开始读取,如果 map 中不存在,说明是最新的,就将消息复制到替换片段上,如果存在,说明不是最新的,就忽略消息,最后把替换片段与原始片段交换。

# 被删除的事件

删除某个键的消息,可发送一个墓碑消息(值为 null),消费者消费到就可知其意,kafka 也会进行清理。

# 何时清理主题

delete 策略不会删除活跃片段,compact 策略也不会清理当前片段。
早的版本在主题数量达到 50% 时进行清理,未来版本使用宽限期。