kafka架构图
在这里插入图片描述
在kafka集群中,会选举出一个broker作为控制器(controller),负责管理集群中所有的分区和副本的状态;
broker控制器选举的原理是借助于zookeeper的临时节点实现: kafka集群启动时,每个broker都会尝试争当控制器,都会往zookeeper的controller节点注册自己,但是由于zookeerper的特性,如果节点已经创建过,再创建就会失败,所以只会有一个broker创建成功,那么创建成功的broker就会成为控制器;此外其他broker都会监听这个controller节点
在这里插入图片描述
由于controller是临时节点,当控制器broker挂机之后,就会断开与zookeeper的会话连接,临时节点也会消失,其它节点监听到controller节点消失后,就会重新争取controller节点。
当controller感知到副本leader所在的broker宕机之后,会在当前副本所在的副本列表中选出第一个副本所在的broker作为副本leader,并且要保证这个broker一定要在副本的ISR(存活的副本broker)集合中,如果第一个不存在,则继续尝试第二个第三个,直到满足;不知道为啥kafka作者为什么不直接在ISR集合里面挑,非得多一步操作
每个消费者消费所在分区的offset都会记录在kafka的内部topic中(__consumer_offsets),kafka默认会为这个topic创建50个分区,用来抵抗高并发; 提交到这个topic的时候,key是当前消费者所处的消费组ID+topic+分区号,value就是当前offset的值,那么kafka会把这个消息发送到哪个分区呢,是由以下公式决定的: hash(consumer group id) % __consumer_offsets主题的分区数(默认50),consumer每次消费前都会从这里获取offset值;
当某个消费组中的消费者挂掉或退出之后,此时就会自动把分配给它的分区分配给其它消费者(没有被指定消费分区的消费者),不仅如此,当有新的消费者加入后也会触发rebalance操作。
通过在消费者客户端配置参数partition.assignment.strategy 来设置分配策略,默认为range
假如目前分区分配如下: 第一个消费者:0,4,8 第二个消费者:1,5,9 第三个消费者:2,6 第四个消费者:3,7 现在如果第四个消费者挂机,则重新分配后如下: 第一个消费者:0,4,8,7 第二个消费者:1,5,9 第三个消费者:2,6,3 如果两个规则冲突,优先保证第一个原则
重要参数acks解释:
HW俗称高水位,又称消费能消费到的最大offset,LEO是broker内部能看到的最大offset, 那么这个最大的offset是怎么产生的呢? 正常情况下,LEO的offset和HW的offset是相同的 当有新消息发送到leader之后,leader的LEO就会增加,这个时候LEO的offset就与HW的offset不一样了,接下来副本开始拉取leader消息,对应的副本LEO也会增加,等到最后一个副本同步完成消息之后,LEO和HW的offset就会一致,这样做的目的是什么呢?是为了「数据的一致性」,保证消息同步完成后才能对消费者可见。
❝ 微信搜一搜【乐哉开讲】关注帅气的我,回复【干货领取】,将会有大量面试资料和架构师必看书籍等你挑选,包括java基础、java并发、微服务、中间件等更多资料等你来取哦。 ❞
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。