kafka-稳定性-控制器

本文详细介绍了Kafka集群中控制器的角色及其选举机制,利用Zookeeper的分布式锁进行控制器选举,防止“脑裂”。控制器负责在节点加入或离开时进行分区Leader选举,并通过epoch确保一致性。同时,讨论了副本分配策略、失效副本的判定及恢复,以及副本与Leader失去同步的情况。Kafka通过ISR确保数据可靠性,并提供了UnderReplicatedPartitions指标来监控集群健康。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

控制器

afka集群包含若干个broker,broker.id指定broker的编号,编号不要重复。
Kafka集群上创建的主题,包含若干个分区。
每个分区包含若干个副本,副本因子包括了Follower副本和Leader副本。
副本又分为ISR(同步副本分区)和OSR(非同步副本分区)
在这里插入图片描述
控制器就是一个broker
控制器除了一般broker的功能,还负责Leader分区的选举
broker选举
集群里第一个启动的broker在Zookeeper中创建临时节点 /controller 。
其他broker在该控制器节点创建Zookeeper watch对象,使用Zookeeper的监听机制接收该节点的
变更。
即:Kafka通过Zookeeper的分布式锁特性选举集群控制器

节点 /myKafka/controller 是一个zookeeper临时节点,其中 “brokerid”:0 ,表示当
前控制器是broker.id为0的broker
在这里插入图片描述
每个新选出的控制器通过 Zookeeper 的条件递增操作获得一个全新的、数值更大的 controller
epoch。其他 broker 在知道当前 controller epoch 后,如果收到由控制器发出的包含较旧epoch 的消
息,就会忽略它们,以防止“脑裂”。
比如当一个Leader副本分区所在的broker宕机,需要选举新的Leader副本分区,有可能两个具有不
同纪元数字的控制器都选举了新的Leader副本分区,如果选举出来的Leader副本分区不一样,听谁的?
脑裂了。有了纪元数字,直接使用纪元数字最新的控制器结果
在这里插入图片描述
当控制器发现一个 broker 已经离开集群,那些失去Leader副本分区的Follower分区需要一个新
Leader(这些分区的首领刚好是在这个 broker 上)。

  1. 控制器需要知道哪个broker宕机了?
  2. 控制器需要知道宕机的broker上负责的时候哪些分区的Leader副本分区?
    下图中, /brokers/ids/0 保存该broker的信息,此节点为临时节点,如果broker
    节点宕机,该节点丢失。
    集群控制器负责监听 ids 节点,一旦节点子节点发送变化,集群控制器得到通知。
    在这里插入图片描述
    控制器遍历这些Follower副本分区,并确定谁应该成为新Leader分区,然后向所有包含新Leader分
    区和现有Follower的 broker 发送请求。该请求消息包含了谁是新Leader副本分区以及谁是Follower副
    本分区的信息。随后,新Leader分区开始处理来自生产者和消费者的请求,而跟随者开始从新Leader副
    本分区消费消息。
    当控制器发现一个 broker 加入集群时,它会使用 broker ID 来检查新加入的 broker 是否包含现有
    分区的副本。如果有,控制器就把变更通知发送给新加入的 broker 和其他 broker,新 broker上的副本
    分区开始从Leader分区那里消费消息,与Leader分区保持同步
    结论:
  3. Kafka使用 Zookeeper 的分布式锁选举控制器,并在节点加入集群或退出集群时通知控制器。
  4. 控制器负责在节点加入或离开集群时进行分区Leader选举。
  5. 控制器使用epoch来避免“脑裂”。“脑裂”是指两个节点同时认为自己是当前的控制器

可靠性保证

概念
  1. 创建Topic的时候可以指定 --replication-factor 3 ,表示分区的副本数,不要超过broker的
    数量。
  2. Leader是负责读写的节点,而其他副本则是Follower。Producer只把消息发送到Leader,
    Follower定期地到Leader上Pull数据。
  3. ISR是Leader负责维护的与其保持同步的Replica列表,即当前活跃的副本列表。如果一个
    Follow落后太多,Leader会将它从ISR中移除。落后太多意思是该Follow复制的消息Follow长
    时间没有向Leader发送fetch请求(参数: replica.lag.time.max.ms 默认值:10000)。
  4. 为了保证可靠性,可以设置 acks=all 。Follower收到消息后,会像Leader发送ACK。一旦
    Leader收到了ISR中所有Replica的ACK,Leader就commit,那么Leader就向Producer发送
    ACK
副本的分配:

当某个topic的 --replication-factor 为N(N>1)时,每个Partition都有N个副本,称作replica。原
则上是将replica均匀的分配到整个集群上。不仅如此,partition的分配也同样需要均匀分配,为了更好
的负载均衡。
副本分配的三个目标:

  1. 均衡地将副本分散于各个broker上
  2. 对于某个broker上分配的分区,它的其他副本在其他broker上
  3. 如果所有的broker都有机架信息,尽量将分区的各个副本分配到不同机架上的broker。
    在不考虑机架信息的情况下:
  4. 第一个副本分区通过轮询的方式挑选一个broker,进行分配。该轮询从broker列表的随机位置
    进行轮询。
  5. 其余副本通过增加偏移进行分配
    在这里插入图片描述
失效副本

失效副本的判定
replica.lag.time.max.ms 默认大小为10000。
当ISR中的一个Follower副本滞后Leader副本的时间超过参数 replica.lag.time.max.ms 指定的值
时即判定为副本失效,需要将此Follower副本剔出除ISR。
具体实现原理:当Follower副本将Leader副本的LEO之前的日志全部同步时,则认为该Follower副
本已经追赶上Leader副本,此时更新该副本的lastCaughtUpTimeMs标识。
Kafka的副本管理器(ReplicaManager)启动时会启动一个副本过期检测的定时任务,而这个定时
任务会定时检查当前时间与副本的lastCaughtUpTimeMs差值是否大于参数
replica.lag.time.max.ms 指定的值。
Kafka源码注释中说明了一般有两种情况会导致副本失效:

  1. Follower副本进程卡住,在一段时间内没有向Leader副本发起同步请求,比如频繁的Full
    GC。
  2. Follower副本进程同步过慢,在一段时间内都无法追赶上Leader副本,比如IO开销过大。
    如果通过工具增加了副本因子,那么新增加的副本在赶上Leader副本之前也都是处于失效状态的。
    如果一个Follower副本由于某些原因(比如宕机)而下线,之后又上线,在追赶上Leader副本之前
    也是出于失效状态。
    失效副本的分区个数是用于衡量Kafka性能指标的重要部分。Kafka本身提供了一个相关的指标,即
    UnderReplicatedPartitions,这个可以通过JMX访问:
kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions

取值范围是大于等于0的整数。注意:如果Kafka集群正在做分区迁移(kafka-reassignpartitions.sh)的候,这个值也会大于0

副本复制

日志复制算法(log replication algorithm)必须提供的基本保证是,如果它告诉客户端消息已被提
交,而当前Leader出现故障,新选出的Leader也必须具有该消息。在出现故障时,Kafka会从挂掉
Leader的ISR里面选择一个Follower作为这个分区新的Leader。
每个分区的 leader 会维护一个in-sync replica(同步副本列表,又称 ISR)。当Producer向broker
发送消息,消息先写入到对应Leader分区,然后复制到这个分区的所有副本中。ACKS=ALL时,只有将
消息成功复制到所有同步副本(ISR)后,这条消息才算被提交。
什么情况下会导致一个副本与 leader 失去同步
一个副本与 leader 失去同步的原因有很多,主要包括:
慢副本(Slow replica):follower replica 在一段时间内一直无法赶上 leader 的写进度。造
成这种情况的最常见原因之一是 follower replica 上的 I/O瓶颈,导致它持久化日志的时间比
它从 leader 消费消息的时间要长;
卡住副本(Stuck replica):follower replica 在很长一段时间内停止从 leader 获取消息。
这可能是以为 GC 停顿,或者副本出现故障;
刚启动副本(Bootstrapping replica):当用户给某个主题增加副本因子时,新的 follower
replicas 是不同步的,直到它跟上 leader 的日志。
当副本落后于 leader 分区时,这个副本被认为是不同步或滞后的。在 Kafka中,副本的滞后于
Leader是根据 replica.lag.time.max.ms 来衡量。

如何确认某个副本处于滞后状态
通过 replica.lag.time.max.ms 来检测卡住副本(Stuck replica)在所有情况下都能很好地工
作。它跟踪 follower 副本没有向 leader 发送获取请求的时间,通过这个可以推断 follower 是否正常。
另一方面,使用消息数量检测不同步慢副本(Slow replica)的模型只有在为单个主题或具有同类流量模
式的多个主题设置这些参数时才能很好地工作,但我们发现它不能扩展到生产集群中所有主题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值