深入Kafka
集群成员关系
Kafka使用zookeeper来维护集群成员信息。每个broker都有一个唯一标识符broker.id。在broker启动时,它把自己的ID注册到zookeeper。Kafka组件订阅zookeeper的brokers/ids/路径,当有broker加入或退出集群时,这些组件就获得通知。
控制器
控制器有一般broker功能之外,还负责分区首领的选举,集群里第一个启动的broker通过zookeeper创建/controller让自己成为控制器。
复制
Kafka 使用主题来组织数据,每个主题被分为若干个分区,每个分区有多个副本。那些副本被保存在 broker上,每个broker可以保存成百上千个属于不同主题和分区的副本。
副本有两种类型:首领副本和跟随着副本。所有生产者和消费者请求都会通过首领副本。跟随着副本通过首领副本复制消息,随时准备提升为新首领。
处理请求
kafka提供了一个二进制协议(基于TCP),制定了请求消息的格式以及broker如何对请求做出响应。
所有请求的消息都包含一个标准消息头:
- Request type
- Request version
- Correlation ID,用于标识请求消息
- Client ID,标识发送请求的客户端
生产请求:生产者发送的请求,包含客户端要写入broker的消息。
获取请求:在消费者和跟随副本需要从broker读取消息时发送的请求。
物理存储
分区分配
副本会尽量与首领不在同一个broker上,策略与DataNode块副本相似。
文件管理
把分区分成若干片段,每个片段包含1GB或一周的数据,如果达到片段上限,就关闭当前文件,并打开一个新文件
正在写入数据的片段叫做活跃片段,活跃片段永远不会被删除。
文件格式
除了键值和偏移量外,消息还包含了消息大小、校验和、消息格式版本号、压缩算法和版本戳。
索引
为了帮助baroker更快定位到指定的偏移量,kafka为每个分区维护了一个索引,索引把偏移量映射到片段文件和偏移量在文件里的位置
拦截器
Interceptor主要用于客户端的定制化控制逻辑。对于生产者而言,拦截器使得用户再消息发送前以及生产者回调逻辑前有机会对消息做一些定制化需求,比如修改消息等。生产者允许用户指定多个拦截器按序作用于同一条信息从而形成一个拦截链。