《Kafka: a Distributed Messaging System for Log Processing》论文阅读
《Kafka: a Distributed Messaging System for Log Processing》论文阅读
这篇论文是LinkedIn在2011年发表的关于Kafka的论文;
论文发表时,kafka还不够完善,使用的人也很少,但优秀的设计,使得它在之后得到广泛应用;
从这篇论文,我们可以窥探kafka最原始的设计理念。
整体架构
topic
- 每种特定类型的message被定义为一种topic
- 每个topic的message,在物理存储时,被分为多个partition
broker
- 负责存储message
- 每个kafka集群,有多个brokers
- 每个broker,负责维护某几个topic的某几个partition
producer
- 向brokers发某种topic的message
consumer
- 从brokers请求某种topic的message
设计原则
Simple storage
partition 存储
- 每个partition对应一个log
- 每个log,由一堆差不多大小的段文件组成
- 每当有新的message时,被追加到最后一个段文件
- 当一定时间后,或者达到一定数量的message后,才flush
- 当flush之后,才向consumer暴露
message 存储
- message没有id,但是有在log中的offset
- consumer向broker请 pull message时,需要带上offset
- broker在内存中cache每个段文件的第一条message的offset
Efficient transfer
- producer submit message时,可以batch submit
- consumer pull message时,也可以batch pull
- broker不做message的cache,而是利用文件系统的page cache
- 避免了double buffering
- broker进程挂掉,但是page cache还在
- broker发message到consumer时,从4次内存拷贝,2次系统调用,减少到了2次内存拷贝,1次系统调用
- 原来的流程
- read data from the storage media to the page cache in an OS
- copy data in the page cache to an application buffer
- copy application buffer to another kernel buffer
- send the kernel buffer to the socket.
- 使用了 sendfile API之后的流程
- read data from the storage media to the page cache in an OS
- send the page cache to the socket.
- 原来的流程
Stateless broker
- message消费到哪个offset,需要由consumer保存,而不是broker保存
- message的删除机制随之就是,支持ttl和超过一定的数量后删除
- consumer如果出现问题,或者处于某种目的,可以从更早的offset重新消费
分布式设计
producer可以submit message到topic的任一个partition,具体哪个partition,可以随机,也可以通过特定分区规则
consumer group
- consumer group 由一个或者多个consumer组成,consumer group之间是独立的
- consumer group整体消费某个topic的全量数据,topic内的某个message只会由1个consumer消费
- 设计上,partition数量远大于consumer group的consumer数量,以便负载均衡
- 不引入master节点,转而依赖高可用系统zk,实现下述功能:
- 检测consumer,broker的增减或者减少
- 触发consumer中的负责均衡进程
- 管理消费关系,和消费的offset
- zk包含broker registry, consumer registry,ownership registry,offset registry
- broker和consumer启动时,会创建broker registry,consumer registry,包含基本信息,作为临时文件
- 每个consumer group包含ownership registry,offset registry
- ownership registry保存了每个partition对应的consumer id,作为临时文件
- offset registry 包含了每个partition对应的消费offset,consumer会进行更新,持久化文件
- 当一开始创建consumer group时,offset要么从最小的,要么从最大的开始
- 每个consumer都会watch zk的文件,当有变化时,触发负载均衡进程
- 触发broker进行复杂均衡的时间可能又先后,当有冲突时,进行重试
一致性
- kafka只保证message会被至少一次消费,当consumer宕机时,可能会重复消费
- kafka保证partition内的message是有序的,但是topic内的message不保证有序
- 添加CRC保证数据正确
- 暂无多副本设计,未来会加上