原创不易,你们对阿超的赞就是阿超持续更新的动力!)
(以免丢失,建议收藏,阿超持续更新中…)
(-----------------------------------------------)
Kafka集群leader选举
- 在kafka集群中,第一个启动的broker会在zk中创建一个临时节点/controller让自己成为控制器。其他broker启动时也会试着创建这个节点当然他们会失败,因为已经有人创建过了。那么这些节点会在控制器节点上创建zk watch对象,这样他们就可以收到这个节点变更的通知。任何时刻都确保集群中只有一个leader的存在。
如果控制器被关闭或者与zk断开连接,zk上的KB是节点马上就会消失。那么其他订阅了leader节点的broker也会收到通知随后他们会尝试让自己成为新的leader,重复第一步的操作。
如果leader完好但是别的broker离开了集群,那么leader会去确定离开的broker的分区并确认新的分区领导者(即分区副本列表里的下一个副本)。然后向所有包含该副本的follower或者observer发送请求。随后新的分区首领开始处理请求。
Kafka创建副本的2种模式——同步复制和异步复制
Kafka动态维护了一个同步状态的副本的集合(a set of In-Sync Replicas),简称ISR,在这个集合中的节点都是和leader保持高度一致的,任何一条消息只有被这个集合中的每个节点读取并追加到日志中,才会向外部通知说“这个消息已经被提交”。
只有当消息被所有的副本加入到日志中时,才算是“committed”,只有committed的消息才会发送给consumer,这样就不用担心一旦leader down掉了消息会丢失。消息从leader复制到follower,我们可以通过决定Producer是否等待消息被提交的通知(ack)来区分同步复制和异步复制。
同步复制流程
同步复制流程:
producer联系zk识别leader;
向leader发送消息;
leadr收到消息写入到本地log;
follower从leader pull消息;
follower向本地写入log;
follower向leader发送ack消息;
leader收到所有follower的ack消息;
leader向producer回传ack。
异步复制流程
异步复制流程:和同步复制的区别在于,leader写入本地log之后,直接向client回传ack消息,不需要等待所有follower复制完成。
既然kafka支持副本模式,那么其中一个Broker里的挂掉,一个新的leader就能通过ISR机制推选出来,继续处理读写请求。
Kafka判断一个broker节点是否存活
依据两个条件:
节点必须可以维护和ZooKeeper的连接,Zookeeper通过心跳机制检查每个节点的连接;
如果节点是个follower,他必须能及时的同步leader的写操作,延时不能太久。Leader会追踪所有“同步中”的节点,一旦一个down掉了,或是卡住了,或是延时太久,leader就会把它移除。
Kafka生产者发送消息确认机制(ack机制)
acks 生产者投递消息的ACK的级别设置
如果需要等到ISR所有的follower副本返回消息leader,可能需要等待,便产生了不同的ack可靠性级别
acks=0 消费者只管投递消息,leader一接收到消息还没有写入磁盘就返回ack
优点:延迟性最低
缺点:如果接收到消息后leader没有写入磁盘就挂掉,从ISR中的follower新选举leader后,会丢失数据
acks=1 消费者只等到leader写入磁盘完成,不管follower副本是否同步完成,就返回ack
问题:leader写入磁盘完成后挂掉了,ISR中的follower还没有来得及同步。从ISR中的follower新选举leader后,会丢失数据。
acks=-1或者all:消费者投递消息后,等待leader和ISR中所有的follower副本同步完成,leader才返回ack。
优点:leader和ISR中所有的follower都同步完成,不丢数据,达到副本数据一致性。
问题:leader在返回ack之前就挂掉了,会从ISR中的follower中选出leader,此时所有leader+follower数据都一致。生产者没有收到leader的ack回应会重试投递,会造成数据重复
kafKa消费消息主要是依靠偏移量进行消费数据的,偏移量是一个不断自增的整数值,当发生重平衡的时候,便于用来恢复数据。
重平衡Rebalance
消费者组内某个消费者实例挂掉后,其他消费者实例自动重新分配订阅主题分区的过程。
发生重平衡时提交偏移量小于客户端处理的最后一个消息的偏移量,那么处于两个偏移量之间的消息就会被重复处理。
如果提交的偏移量大于客户端的最后一个消息的偏移量,那么处于两个偏移量之间的消息将会丢失。
怎么解决:
偏移量手动提交 ; ------------------> auto.commit = false;
避免消息的重复消费 / 幂等性 ; ------> 持久化已经成功消费的消息 ; 判定 ;
KafkaISR机制
ISR(IN-SYNC Replication):维护了与leader信息一致的follower副本的信息,当leader挂掉的时候 就从这个ISR中选举。
当leader挂掉的时候,由controller会在follower副本中选举出一个leader。但是这个剩余follower副本有一个条件,就是follower必须在ISR列表中。
leader和ISR中的follower副本都同步完成时,就返回ack。
ISR信息存放在zookeeper的topic信息中,由kafka动态维护
leader如何动态维护ISR
- replica.lag.max.messages
默认值4000如果某个follower副本落后leader副本的消息数超过了这个值,那么leader副本就会把该follower副本从ISR中移除。
在0.9之后的版本中已经移除。
存在问题:生产者批量产生多余4000条的消息,发送给leader,此时ISR中所有的follower副本全部落后于leader,都会被剔除ISR。然后又要有新的follower副本加入ISR(问题:频繁操作ISR,还要操作zookeeper)。
2.replica.lag.time.max.ms
follower副本响应leader副本的最长等待时间。超过这个时间将会从ISR中移除。
生产者生产消息进行投递——>分区中的leader——>通知到ISR中所有的follower副本进行同步数据——>ISR中所有的follower告知leader同步完成——>leader返回ack——>生产者
---------------------------面试题总结-----------------------------
Java基础知识点总结
MyBatis常见面试题总结
Spring常见面试题总结
SpringMVC常见面试题总结
SpringBoot常见面试题总结
消息中间件常见面试题总结
Kafka常见面试题
Redis面试题总结
SQL常见面试题总结
Dubbo常见面试题总结
SpringCloud常见面试题总结
TCP和UDP详解
数据库事务详解