kafka创建topic时如何将分区放置到不同的broker中

首先介绍下相关的概念

  • producer 发送数据的一方

  • consumer 消费数据的一方

  • consumer group 消费者组,当消费者组中的某个消费者消费掉了分区中的某一条消息时,该组中的其他消费者不会在消费该条数据 消费者必须指定消费者组

  • partition 使kafka能够横向扩展,一个topic可以有多个分区,在创建topic时 kafka根据内部的负载均衡算法 将分区均匀的分布在多个broker上,分区可以提高系统的吞吐量,kafka只在partition中是有序的

  • replica 使kafka具有较高的容错性,当某一台broker挂掉时,仍然有broker包含该挂掉的broker上的数据,备份是针对topic的partition而言的,当备份数为n时就代表每一个partition 共有n个副本

  • offset 偏移量,记录partition中要消费的数据起始位置

kafka在创建topic时是如何将分区均匀的分布在整个集群上了

1 将所有存活的broker和待分配的partition的排序(从0开始)
2 将第i个partition分配到第(i mod n)个broker上,这个partition相当于第i个副本
3 将第i个partion的第j个副本分配到第((i+j)mod n)个broker上

假设现在有5个broker,分区数为5 ,副本为3,按照上面的说法,topic最终在整个集群的样子如下:
kafka创建topic时如何将分区放置到不同的broker中_第1张图片

但事实真的是这样的吗?实际上如果真按照这种算法,会存在以下明显几个问题:

所有主题的第一个分区都是存放在第一个Broker上,这样会造成第一个Broker上的分区总数多于其他的Broker,这样就失去了负载均衡的目的;

如果主题的分区数多于Broker的个数,多于的分区都是倾向于将分区发放置在前几个Broker上,同样导致负载不均衡。

所以其实上面的算法不准确。严格来说,上面的算法只是Kafka分配分区的一种特例(下面介绍算法部分会说明)。下面我们来看看 Kafka 内部到底是如何将分区分配到各个 Broker 中的,其具体算法实现函数就是 assignReplicasToBrokers,如下:

kafka创建topic时如何将分区放置到不同的broker中_第2张图片
从上面的算法可以看出:

1 副本因子不能大于 Broker 的个数;

2 第一个分区(编号为0)的第一个副本(编号为0)放置位置是随机从 brokerList 选择的;

3 其他分区的第一个副本放置位置相对于第0个分区依次往后移。也就是如果我们有5个 Broker,5个分区,假设第一个分区放在第四个 Broker 上,那么第二个分区将会放在第五个 Broker 上;第三个分区将会放在第一个 Broker 上;第四个分区将会放在第二个 Broker 上,依次类推;

4 剩余的副本相对于第一个副本放置位置其实是由 nextReplicaShift 决定的,而这个数也是随机产生的

你可能感兴趣的:(Java服务端技术)