【kafka】分区副本分配算法解析

本文深入解析Kafka的分区副本分配算法,探讨其如何确保副本均衡分布于不同broker,增强系统的可用性和负载均衡。内容包括算法功能、实现原理、源码分析,特别是countNextReplicaIndex函数的关键特性。
摘要由CSDN通过智能技术生成

kafka分区副本分配算法解析

最近在看《深入理解Kafka:核心设计与实践原理 》来系统学习kafka,第一个令我想深入了解的就是这个知识点:分区副本分配算法

算法功能

各个分区副本 均衡分配不同的broker节点 中,既避免因为某个broker宕机导致整个分区不可用,也实现了各个broker节点的负载均衡

broker节点可以视为 不同的服务器

引入

我们看看分区副本分配算法的效果

有三个kafka broker节点

  • 步骤
    • 创建一个 有 4 个分区,每个分区有2个副本的 topic topic-hello,(可视为有 4*2 = 8个分区副本)
    • 查看topic-hello各个分区分布情况
➜  bin ./kafka-topics.sh --bootstrap-server 172.16.17.188:9092 --create --topic topic-hello --partitions 4 --replication-factor 2
Created topic topic-hello.
➜  bin ./kafka-topics.sh --bootstrap-server 172.16.17.188:9092 --describe --topic topic-hello                                    
Topic: topic-hello	PartitionCount: 4	ReplicationFactor: 2	Configs: segment.bytes=1073741824
	Topic: topic-hello	Partition: 0	Leader: 2	Replicas: 2,1	Isr: 2,1
	Topic: topic-hello	Partition: 1	Leader: 1	Replicas: 1,0	Isr: 1,0
	Topic: topic-hello	Partition: 2	Leader: 0	Replicas: 0,2	Isr: 0,2
	Topic: topic-hello	Partition: 3	Leader: 2	Replicas: 2,0	Isr: 2,0

如上图我们可以得到,各个分区副本分在哪个broker里面:

## 描述A
分区0 分在 [2,1] 
分区1 分在 [1,0] 
分区2 分在 [0,2] 
分区3 分在 [2,0] 

所以,各个broker拥有的分区情况如下:

## 描述B
broker-0 有分区 [1,2,3]
broker-1 有分区 [0,1]
broker-2 有分区 [1,2,3]

结合上述的算法功能,如果人工来分配在三个broker里分配 8 个分区副本,人工也会这样分配成这样的3+3+2=8的模式,因为这样对负载也相对均衡;各个副本也分布在不同的 broker节点中,也就更为保险。
其实上述两种描述,描述的是算法的不同方面:

  • 描述A: 算法实现的 保险功能
  • 描述B:算法实现的 负载均衡 功能

实现方法

原理分析

以下只考虑 fixedStartIndex=-1startPartitionId=-1的情况

前提
  • 副本因子 <= broker数量
  • 知道要总共要处理多少个资源(很多负载均衡算法就是不知道这个)
关键点
  • 随机产生一个副本距离replicaGap——为了多次通过此算法分配时,避免固定的方案,这样会导致负载不均衡
  • 选出第一个分区所属的broker

    int firstReplicaIndex = (currentPartitionId + startIndex) % brokerList.size();
    因为startIndex是随机的,因此firstReplicaIndex也是随机的随机是为了多次通过此算法分配时,不能每一次都从同一个 broker 开始,对其不公平

源码分析

  • 主程序
  /**
     * 分区副本分配 主要内容
     * @param partitionCount 分区总数
     * @param replicaFactor 分区副本因子,也就是每个分区有多少个副本
     * @param brokerList broker节点列表,这里为了好区分,已经用名字代替,实际算法中是一个 List<Integer>
     * @param fixedStartIndex 默认为-1,此时随机产生一个在 [0.brokerList.size()-1]的随机数 n,那么 broker-n 就是容纳 第一个分区的 第一个broker
     * @param startPartitionId 默认为 -1,-1意味着第一个处理的分区是 分区0 ,否则 第一个处理的分区是 分区startPartitionId
     * @return key 为分区id,value 为其分区副本所在的brokerList
     */
    private static Map<Integer, List<String>> allocatePartitionReplica(int partitionCount, int replicaFactor, List<String> brokerList,
                                                                       int fi
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值