kafka常见的集群部署模式
1. Hub架构。一个中心的kafka集群做中央调度,对应多个本地的kafka集群。
变种是一个关键的kafka集群对应一个非关键的跟随者
2. 双活架构。 多个集群之间保持数据同步。
3. 主备架构。有两个集群,平常只用主集群, 另外一个集群只有当主集群出了问题才用。
4. 延展集群。单个数据中心故障的时候,重新定位到另一个数据中心 。
比如主题副本列表
分区数据的拷贝。分为两种类型: 1. 首领副本。负责分清那个跟随者状态与自己一致。每个分区都有一个,所有生产者和消费者请求都会经过它。 2. 跟随者副本。首领以外的副本。不处理客户端的请求。仅从首领复制消息,如果首领崩溃,他们中的同步副本会被提升为新首领。
在有新消息到达时,跟随者会向首领发送获取数据的请求。一个跟随者副本首先请求消息1,然后消息2,然后消息3;如果没有收到这3个消息的响应,不会再次请求消息4。
持续请求最新消息的副本也被称作同步的副本
如果跟随者发送了请求消息4,,那么知道消息被同步了,如果跟随者10s内没有请求消息,或者没有请求最新的消息,此跟随者被当做不同步。
没有同步的副本是不可能成为新的首领的
创建主题时候选定的首领即分区首选首领。如果首选首领不是当前首领,并且该副本是同步的,就会触发首领选举,使得首选首领称为当前首领
kafka具备默认的分区器。如果key没有,就通过Round robin算法将消息发送到各个可用的分区上,如果key存在,就对键进行散列
只有主题分区数不可变的时候,映射才有用
创建主题的时候,kafka先决定broker的分配。它的总原则是:broker之间平均分步分区副本
;每个分区的副本分布在不同的broker上
轮询,比如broker0是首领,那么1是跟随者,类推。如果有机架信息,会尽可能使得副本分配到不同机架上。
分配好副本之后,选择数据存储目录,每个分区会有单独的目录,新的分区总被添加到分区数小的目录里面
假设有新磁盘,那么新分区会在新磁盘上。注意这里没有考虑分区的大小,仅仅看数量
控制器本身是一个兼具分区首领选举的broker
1. 集群中第一个启动的broker通过在zk中创建一个临时节点 /controller 使自己成为控制器。其它节点启动时同样会进行这个操作,但只会收到 节点点存在 的异常,其它节点只会在 控制器节点上创建zk watch对象接收节点的变更通知
确保集群只有一个控制器
2. 控制器关闭或者异常时,watch对象告知各个broker,他们进而尝试成为控制器,第一个成功的会成为控制器,其它则创建watch对象。新的控制器会获得更大的controller epoch,其它broker获知当前的epoch之后,如果发现比当前要小的epoch则忽略
3. 有节点退出时,如果broker包含首领,则控制器遍历分区确定新首领,然后向包含新首领或现有的跟随者发请求消息,告知谁是新首领和谁是分区跟随者。新broker加入时,检查broker ID是否有现成的分区副本,有的话变更消息发送给新的broker和其它broker,新broker上副本开始从首领复制消息
新增分区会发生分区重分配。
1. 新加入的消费者它读取的消息是原本属于其它消费者读取的消息,一个消费者关闭或者崩溃则离开群组,原本应该被它读取的消息由其它消费者接受。 2. 再均衡。即分区的所有权从一个消费者转移到另一个消费者。这个过程中,消费者群无法处理消息。 3. 分区的所有权则通过消费者向被指派的 群组协调器 的broker发送心跳来维持,同时消费者的心跳行为也用来维持和群组的从属关系。如果消费者停止发送心跳的时间足够长,会话会过期,群组协调器认为它已经死亡,触发再均衡
第一个加入消费组的是群组。负责给每一个消费者分配分区
可以。一个消费者可以自己订阅主题并加入消费组,或者为自己分配分区
不能同时做这两件事
不过分配分区如果主题添加了新的分区,消费者不会收到通知,需要周期性的调用consumer.partitionsFor方法或者重启。
自己分配分区后是不会发生再均衡以及手动查找分区,其余一样
消费者从属于一个消费群组,一个群组里的消费者订阅同一个主题,每个消费者接受主题一部分分区的消息。消费者的数量应该小于等于分区的数量,如果消费者的数量超过分区数,那么超过部分会被闲置。不同消费组群互相不影响,如果一个应用要处理多个主题,可以让多个主题公用一个消费者群组