• Kafka 0.8 副本同步机制理解


    Kafka的普及在很大程度上归功于它的设计和操作简单,如何自动调优Kafka副本的工作,挑战之一:如何避免follower进入和退出同步副本列表(即ISR)。如果某些topic的部分partition长期处于“under replicated”状态,会增加数据丢失的概率。Kafka通过“多副本机制”实现高可用,当Kafka集群中一个Broker失效情况下仍然保证服务可用。

    Kafka日志复制算法保证,如果leader发生故障或挂掉,一个新leader被选举并且客户端的消息成功写入。Kafka确保从同步副本列表中选举一个副本为leader。


    0.副本知识

    每个Partition有一个预写式日志文件,每个Partition都由一系列有序的、不可变的消息组成,这些消息被连续的追加到Partition中,Partition中的每个消息都有一个连续的序列号叫做offset, 确定它在分区日志中唯一的位置。
    image

    • leader处理对这个partition的所有读写请求。
    • follower会去复制leader上的数据。

    1. in sync 条件

    Leader负责跟踪同步副本列表中所有follower滞后状态。
    同步中的(in sync),Kafka判断一个节点是否活着有两个条件:

    1. 节点必须可以维护和ZooKeeper的连接,Zookeeper通过心跳机制检查每个节点的连接。——由参数request.required.acks决定,如果是这个参数生效而移除一个follower,说明这个follower 失效或者死亡。
    2. 如果节点是个follower,他必须能及时的同步leader的写操作,延时不能太久。—— 由参数replica.lag.max.messages决定的,如果是这个参数生效而移除一个follower,说明这个follow是一个“慢副本”。
    • 一条消息只有被“in sync” list里的所有follower都从leader复制过去才会被认为已提交。这样就避免了部分数据被写进了leader,还没来得及被任何follower复制就宕机了,而造成数据丢失。
    • 而对于producer而言,它可以选择是否等待消息commit,这可以通过request.required.acks来设置。
    • 对于Consumer而言,只能看见被commit的消息。

    1.1问题:

    1. 被移除后的under replica的follower 会继续拉取leader的数据,等追赶上之后,会被重新加入到“同步副本”。
    2. 一个消息什么时候被认为是提交的?(意味着可以被consumer消费)
    • 直到follower Broker 从同步副本列表中移除
    • 或者追赶上leader log end offset,最新的消息才会认为提交。
    1. 是什么原因导致分区的副本与leader不同步
    • 慢副本:在一定周期时间内follower不能追赶上leader。最常见的原因之一是I / O瓶颈导致follower追加复制消息速度慢于从leader拉取速度。
    • 卡住副本:在一定周期时间内follower停止从leader拉取请求。follower replica卡住了是由于GC暂停或follower失效或死亡。
    • 新启动副本:当用户给主题增加副本因子时,新的follower不在同步副本列表中,直到他们完全赶上了leader日志。
    1. kafka-0.8 相关集群参数配置
      replica.lag.time.max.ms=10000 // 根据队列流量大小和集群负载情况做出判断并设置一个合适值
      replica.lag.max.messages=4000
      

    2. Leader 选举

    当leader宕机了,怎样在follower中选举出新的leader?

    • 实际上,leader election算法非常多,比如Zookeper的Zab, Raft和Viewstamped Replication。而Kafka所使用的leader election算法更像微软的PacificA算法。

    一种非常常用的选举leader的方式是“majority vote”(“少数服从多数”),但Kafka并未采用这种方式。这种模式下,如果我们有2f+1个replica(包含leader和follower),那在commit之前必须保证有f+1个replica复制完消息,为了保证正确选出新的leader,fail的replica不能超过f个。---(类似pasox算法)

    • 缺点:需要的replica的数量太多,造成性能瓶颈。

    leader 选举算法

    Kafka在Zookeeper中动态维护了一个ISR(in-sync replicas) set,这个set里的所有replica都跟上了leader,只有ISR里的成员才有被选为leader的可能。在这种模式下,对于f+1个replica,一个Kafka topic能在保证不丢失已经ommit的消息的前提下容忍f个replica的失败。在大多数使用场景中,这种模式是非常有利的。

    在ISR中至少有一个follower时,Kafka可以确保已经commit的数据不丢失,但如果某一个partition的所有replica都挂了,就无法保证数据不丢失了。这种情况下有两种可行的方案:

    • 等待ISR中的任一个replica“活”过来,并且选它作为leader
    • 选择第一个“活”过来的replica(不一定是ISR中的)作为leader

    这就需要在可用性和一致性当中作出一个简单的平衡。(Kafka0.8.*使用了第二种方式。)


    3.平衡partition

    1. 默认情况下,kafka以RoundRobin方式写各个partition,让各个partition的消息量均衡。
    2. 平衡partition的leader在所有的broker上。

    优化leadership election的过程也是很重要的,毕竟这段时间相应的partition处于不可用状态。

    一种简单的实现是暂停宕机的broker上的所有partition,并为之选举leader。实际上,Kafka选举一个broker作为controller,这个controller通过watch Zookeeper检测所有的broker failure,并负责为所有受影响的parition选举leader,再将相应的leader调整命令发送至受影响的broker,过程如下图所示。
    image


    4.Controller

    负责leader 选举,每个broker都可成为Controller。

    它可以批量的通知leadership的变化,从而使得选举过程成本更低。如果controller失败了,所有broker都会尝试在Zookeeper中创建/controller->{this broker id},如果创建成功(只可能有一个创建成功),则该broker会成为controller。

    Controller对Broker failure的处理过程

    1. Controller在Zookeeper的/brokers/ids节点上注册Watch。一旦有Broker宕机(本文用宕机代表任何让Kafka认为其Broker die的情景,包括但不限于机器断电,网络不可用,GC导致的Stop The World,进程crash等),其在Zookeeper对应的Znode会自动被删除,Zookeeper会fire Controller注册的Watch,Controller即可获取最新的幸存的Broker列表。
    2. Controller决定set_p,该集合包含了宕机的所有Broker上的所有Partition。
    3. 对set_p中的每一个Partition:
    3.1 从/brokers/topics/[topic]/partitions/[partition]/state读取该Partition当前的ISR。
      3.2 决定该Partition的新Leader。如果当前ISR中有至少一个Replica还幸存,则选择其中一个作为新Leader,新的ISR则包含当前ISR中所有幸存的Replica。否则选择该Partition中任意一个幸存的Replica作为新的Leader以及ISR(该场景下可能会有潜在的数据丢失)。如果该Partition的所有Replica都宕机了,则将新的Leader设置为-1。
      3.3 将新的Leader,ISR和新的leader_epoch及controller_epoch写入/brokers/topics/[topic]/partitions/[partition]/state。注意,该操作只有Controller版本在3.1至3.3的过程中无变化时才会执行,否则跳转到3.1。
    
    1. 直接通过RPC向set_p相关的Broker发送LeaderAndISRRequest命令。Controller可以在一个RPC操作中发送多个命令从而提高效率.

     Broker failover顺序图如下所示。
    image 


    5. 消息保障

    kafka能够保障以下两点:

    • At most once 消息可能会丢,但绝不会重复传输
    • At least once 消息绝不会丢,但可能会重复传输

    对于Producer

    • 发送不管,at most once
    • 发送管ack,at least once

    对于Consumer

    • 记录Offset,at least once。
  • 相关阅读:
    把文本文件数据快速导入Sql Server
    db4o, 看上去很美
    从《黑暗森林》事件谈下我对网络时代正版,盗版的看法
    viewDidUnload 和 dealloc 的区别(转)
    (翻译)cocoaasyncsocket 异步Socket
    iPhone的Socket编程使用开源代码之AsyncSocket(转)
    iphone之开源类库工具
    ObjectC 中各数据类型转换 NSData转NSString,Byte,UIImage
    iphone开发ObjectiveC新特性──类别与协议(转)
    让WebForm异步起来(转)
  • 原文地址:https://www.cnblogs.com/byrhuangqiang/p/6369176.html
Copyright © 2020-2023  润新知