kafak-kafka中的选举是怎么回事?

Kafka Controller:它负责管理整个集群中所有分区和副本的状态等工作。比如当某个分区的leader副本出现故障时,由控制器负责为该分区选举新的leader副本。再比如当检测到某个分区的ISR集合发生变化时,由控制器负责通知所有broker更新其元数据信息。

kafka Controller 选举:在Kafka集群中会有一个或多个broker,其中有一个broker会被选举为控制器(Kafka Controller)。

ISR: 
“in-sync” replicas,每个Partition有一个leader与多个follower,leader会维护一个与其基本保持同步的Replica列表,该列表称为ISR(in-sync Replica),每个Partition都会有一个ISR,而且是由leader动态维护。如下方式可以查到分区的Isr:
./bin/kafka-topics --zookeeper kafka-node-01:2181 --describe --topic test-001
Topic:test-001    PartitionCount:5    ReplicationFactor:2    Configs:
    Topic: test-001    Partition: 0    Leader: 2    Replicas: 2,1    Isr: 2,1
    Topic: test-001    Partition: 1    Leader: 3    Replicas: 3,2    Isr: 2,3
    Topic: test-001    Partition: 2    Leader: 4    Replicas: 4,3    Isr: 3,4
    Topic: test-001    Partition: 3    Leader: 5    Replicas: 5,4    Isr: 5,4
    Topic: test-001    Partition: 4    Leader: 1    Replicas: 1,5    Isr: 1,5

分区理解:

Kafka会将接收到的消息进行分区(partition),每个主题(topic)的消息有不同的分区,为了保证高可用,每个分区都会有一定数量的副本(replica)。这样如果有部分服务器不可用,副本所在的服务器就会接替上来,保证应用的持续性。

为了保证较高的处理效率,消息的读写都是在固定的一个副本上完成,这个副本就是所谓的Leader,而其他副本则是Follower,而Follower则会定期地到Leader上同步数据。

如果某个分区所在的服务器出了问题,不可用,kafka会从该分区的其他的副本中选择一个作为新的Leader。之后所有的读写就会转移到这个新的Leader上。现在的问题是应当选择哪个作为新的Leader。显然,只有那些跟Leader保持同步的Follower才应该被选作新的Leader。

如果没有一个Leader,所有Replica都可同时读/写数据,就无法保证数据的一致性和有序性。而引入Leader后,只有Leader负责数据读写,Follower只向Leader顺序Fetch数据(N条通路),系统更加简单且高效。 

Kafka会在Zookeeper上针对每个Topic维护一个称为ISR(in-sync replica,已同步的副本)的集合,该集合中是一些分区的副本。只有当这些副本都跟Leader中的副本同步了之后,kafka才会认为消息已提交,并反馈给消息的生产者。如果这个集合有增减,kafka会更新zookeeper上的记录。

       只有副本跟Leader同步后,才加入ISR列表。
  如果某个分区的Leader不可用,Kafka就会从ISR集合中选择一个副本作为新的Leader。
  显然通过ISR,kafka需要的冗余度较低,可以容忍的失败数比较高。假设某个topic有f+1个副本,kafka可以容忍f个服务器不可用。

分区leader副本的选举:

  1. 当创建分区(创建主题或增加分区都有创建分区的动作)或分区上线(比如分区中原先的leader副本下线,此时分区需要选举一个新的leader上线来对外提供服务)的时候都需要执行leader的选举动作。
  2. 当分区进行重分配(reassign)的时候也需要执行leader的选举动作。
  3. 当某节点被优雅地关闭(也就是执行ControlledShutdown)时,位于这个节点上的leader副本都会下线,所以与此对应的分区需要执行leader的选举。

如果当一个broker停止或者crashes时,所有本来将它作为leader的分区将会把leader转移到其它broker上去。这意味着当这个broker重启时,它将不再担任何分区的leader,kafka的client也不会从这个broker来读取消息,从而导致资源的浪费,并且可能造成各个节点负载不均衡。

比如下面的broker 7是挂掉重启的,我们可以发现Partition 1虽然在broker 7上有数据,但是由于它挂了,所以kafka重新将broker 3当作该分区的Leader,然而broker 3已经是Partition 6的Leader了。

[iteblog@www.iteblog.com ~]$ kafka-topics.sh --topic iteblog   \
--describe --zookeeper www.iteblog.com:2181
 
Topic:iteblog PartitionCount:7  ReplicationFactor:2 Configs:
  Topic: iteblog  Partition: 0  Leader: 1 Replicas: 1,4 Isr: 1,4
  Topic: iteblog  Partition: 1  Leader: 3 Replicas: 7,3 Isr: 3,7
  Topic: iteblog  Partition: 2  Leader: 5 Replicas: 5,7 Isr: 5,7
  Topic: iteblog  Partition: 3  Leader: 6 Replicas: 6,1 Isr: 1,6
  Topic: iteblog  Partition: 4  Leader: 4 Replicas: 4,2 Isr: 4,2
  Topic: iteblog  Partition: 5  Leader: 2 Replicas: 2,5 Isr: 5,2
  Topic: iteblog  Partition: 6  Leader: 3 Replicas: 3,6 Isr: 3,6

系统默认配置了auto.leader.rebalance.enable=true,自动平行leader,如果设置为flase,就需要手工执行kafka-preferred-replica-election.sh脚步来平行一次leader。详细参考:Kafka集群Leader均衡(Balancing leadership)

下面是Leader平衡的结果:

[iteblog@www.iteblog.com ~]$ kafka-topics.sh --topic iteblog --describe \
--zookeeper www.iteblog.com:2181
 
Topic:iteblog PartitionCount:7  ReplicationFactor:2 Configs:
  Topic: iteblog  Partition: 0  Leader: 1 Replicas: 1,4 Isr: 1,4
  Topic: iteblog  Partition: 1  Leader: 7 Replicas: 7,3 Isr: 3,7
  Topic: iteblog  Partition: 2  Leader: 5 Replicas: 5,7 Isr: 5,7
  Topic: iteblog  Partition: 3  Leader: 6 Replicas: 6,1 Isr: 1,6
  Topic: iteblog  Partition: 4  Leader: 4 Replicas: 4,2 Isr: 4,2
  Topic: iteblog  Partition: 5  Leader: 2 Replicas: 2,5 Isr: 5,2
  Topic: iteblog  Partition: 6  Leader: 3 Replicas: 3,6 Isr: 3,6

可以看出broker 7重新变成Partition 1的Leader了。 

其他:

replica

分布式系统必然要实现高可靠性,而目前实现的主要途径还是依靠冗余机制——简单地说,就是备份多份日志。这些备份日志在Kafka中被称为副本(replica),它们存在的唯一目的就是防止数据丢失。

副本分为两类:领导者副本(leader replica)和追随者副本(follower replica)。follower replica 是不能提供服务给客户端的,也就是说不负责响应客户端发来的消息写入和消息消费请求。它只是被动地向领导者副本(leader replica)获取数据,而一旦leader replica所在的broker宕机,kafka会从剩余的replica中选举出新的leader继续提供服务。

ISR

ISR的全称是in-sync replica,翻译过来就是与leader replica保持同步的replica集合。这是一个特别重要的概念。前面讲了很多关于Kafka的副本机制,比如一个partition可以配置N个replica,那么这是否就意味着该partition可以容忍N-1个replica失效而不丢失数据呢?答案是“否”!

Kafka为partition动态维护一个replica集合。该集合中的所有replica保存的消息日志都与leader replica保持同步状态。只有这个集合中的replica才能被选举为leader,也只有该集合中所有replica都接收到了同一条消息,kafka才会将该消息置于“已提交”状态,即认为这条消息发送成功。回到刚才的问题,Kafka承诺只要这个集合中至少存在一个replica,那些“已提交”状态的消息就不会丢失——记住这句话的两个关键点:①ISR中至少存在一个“活着的”replica;②“已提交”消息。

正常情况下,partition的所有replica(含leader replica)都应该与leader replica保持同步,即所有replica都在ISR中。因为各种各样的原因,一小部分replica开始落后于leader replica的进度。当滞后到一定程度时,Kafka会将这些replica“踢”出ISR。相反地,当这些replica重新“追上”了leader的进度时,那么Kafka会将它们加回到ISR中。这一切都是自动维护的,不需要用户进行人工干预,因而在保证了消息交付语义的同时还简化了用户的操作成本。

 

更多参考:

https://blog.csdn.net/u013256816/article/details/89369160

https://www.cnblogs.com/aspirant/p/9179045.html

https://www.cnblogs.com/swordfall/p/10193336.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值