架构
- Topic : Kafka将消息种子(Feed)分门别类, 每一类的消息称之为话题(Topic).
- Producer:发布消息的对象称之为话题生产者(Kafka topic producer)
- Consumer:订阅消息并处理发布的消息的种子的对象称之为话题消费者(consumers)
- Broker:已发布的消息保存在一组服务器中,称之为Kafka集群。集群中的每一个服务器都是一个代理(Broker). 消费者可以订阅一个或多个话题,并从Broker拉数据,从而消费这些已发布的消息。
存储
每个topic分成多个分区,每个对于一个逻辑日志。逻辑日志对于多个物理文件。生产者发布消息时,broker将消息追加入最后一个物理文件中。物理文件按照大小或者时间flush,只有flush后的数据能被消费者看到。kafka的消息没有id,是通过offset来确定位置的。
broker
broker是无状态的,消费者自己维护状态。数据在broker的保留策略是按照时间来保存的,通常是7天自动删除。
对于broker来说,分区分布在多个服务器上,每个服务器处理他分到的分区。每个分区有1个leader,0到多个follower,leader处理分区全部请求,follower只是复制。leader挂了以后会有一个follower变成新的leader
生产者
生产者往某个topic发布消息是,也负责选择发到哪个分区,一般是轮询或者由开发者定。
消费者
消费者消费时有两点:
- 同一时间每个topic的一个分区只能被一个消费者消费,这要求分区数必须大于消费者的数量。
- 消费者自己利用zookeeper来调节分区分配。zookeeper负责以下三点
- 探测broker和consumer的添加或移除。
- 当1发生时触发每个消费者进程的重新负载。
- 维护消费关系和追踪消费者在分区消费的消息的offset。
交付保证
- kafka保证至少一次交付。如果消费者挂了,那么新的消费者会按照最后提交到zookeeper的Offset接管消息,这样可能会有重复,但是不会丢失
- 保证来此自同一分区的消息投递顺序
副本管理和恢复
kafka节点活着的标志是
节点在zookeeper注册的session还在且可维护(基于zookeeper心跳机制)
如果是slave则能够紧随leader的更新不至于落得太远。kafka采用in sync来代替“活着”。如果follower挂掉或卡住或落得很远,则leader会移除同步列表中的in sync。至于落了多远才叫远由replica.lag.max.messages配置,而表示复本“卡住”由replica.lag.time.max.ms配置。kafka不处理拜占庭将军问题。
对于消息是否提交,判断是用是2f+1策略,意思是只要有f+1的复本已获得了leader的最新的消息,那么就认为该消息被提交了。生产者可以选择是否等待消息提交
当leader挂了的时候,我们需要选择一个follow作为新leader,但是要保证follower的数据是最新的。在2f+1的策略下,至少有f+1的副本已经获得了leader消息时该消息才认为被接收,所有可以允许最多f个机器同时挂掉(含leader),以保证至少有一个节点的消息是最新的。
如果所有节点挂了,有两种选择:
- 等待ISR(in-sync)的复本恢复,然后选择该复本为leader(这需要该复本仍然有所有数据的情况)
- 选择第一个复本作为leader(无关是否是ISR状态)
参考文献
本文采用创作共用保留署名-非商业-禁止演绎4.0国际许可证,欢迎转载,但转载请注明来自http://thousandhu.github.io,并保持转载后文章内容的完整。本人保留所有版权相关权利。