Kafka 分区管理

优先副本的选举

当我们输入以下命令,

1
kafka-topics.sh  --zookeeper zookeeper:2181  --describe  --topic test4

查看主题详情时,会展示如下信息
image.png

其中 Replicas 就是 AR

现,我们将 brokerId 2 的机器重启,kafka 会从 Isr 副本中选出一个新的节点作为 leader, brokerId 为 2 的机器重启后,只能作为 follower
image.png

从上图,可以看到,Partition 1 选出了新的 Leader 3,从而导致,brokerId 3 负载较高。

为此,kafka 引进 优先副本概念
优先副本为 Replicas 列表中的第一个节点。对于 Partition 1 来说就是 brokerId 2 的节点。也就是说,Paritition 1 按理 Leader 应该为 2,而非 3。

分区自动平衡

kafka 可在 broker 端,通过 auto.leader.rebalance.enable 控制是否开启分区自动平衡,该参数默认为 true,即默认开启。
如果开启分区自动平衡,kafka 会定时轮询所有的 broker 节点,计算每个 broker 节点分区不平衡率(不平衡的 leader 数 / 分区总数 )是否超过 leader.imbalance.per.broker.percentage 参数配置的比例,默认为 10%。如果超过,则自动执行分区平衡。其中,定时轮询任务的执行周期默认为 300秒,由参数 leader.imbalance.check.interval.seconds

这里不建议在线上开启分区自动化平衡

分区手动平衡

kafka 中提供 kafka-preferred-replica-election.sh 脚本对 leader 分区重新平衡。

在这里,我们需要对 主题 test4 中的 partition 1 进行重分配

  1. 创建 test4_election.json 文件(文件自己命名)
1
2
3
4
5
6
7
8
{
"partitions": [
{
"partition": 1,
"topic": "test4"
}
]
}
  1. 输入命令,指定刚才创建的文件
1
kafka-preferred-replica-election.sh --zookeeper zookeeper:2181 --path-to-json-file test4_election.json

分区重分配

当我们需要提前下线一个节点,或者新增一个节点时,都需要对分区进行重分配。kafka 提供 kafka-reassign-partitions.sh 脚本执行分区重分配。

先看执行前test4 的分区如下
image.png

现要让 brokerId 2 节点下线。那么就需要对 parition 0, partition 1 重新分配。

  1. 编写 test4_reassign.json 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"partitions": [
{
"topic": "test4",
"partition": 1,
"replicas": [1,3]
},
{
"topic": "test4",
"partition": 0,
"replicas": [1,3]
}
],
"version": 1
}
  1. 执行命令
1
kafka-reassign-partitions.sh --zookeeper zookeeper:2181 --execute --reassignment-json-file test4_reassign.json

执行完后,新的分区分配如下
image.png

分区重分配的基本原理是:broker 控制器为每个分区新增副本,然后再复制 leader 副本的数据。复制完毕之后,最后将旧副本删除掉。

复制限流

从分区重分配的原理了解到,复制的时候会发生大量的网络传输,此时如果业务流量特别大,那么可能会对当前业务造成影响,因此需要对复制进行限流。

kafka-reassign-partitions.sh 限流

1
kafka-reassign-partitions.sh --zookeeper zookeeper:2181 --execute --reassignment-json-file test4_reassign.json --throttle 1024

修改副本因子

使用 kafka-reassign-partitions.sh,进行副本因子的修改。

  1. 生成重分配 json
1
kafka-reassign-partitions.sh --zookeeper zookeeper:2181 --generate --topics-to-move-json-file test5_reassign.json --broker-list 1,2,3

image.png

  1. 将红色框的内容,复制的 json 文件中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{
"version":1,
"partitions":[
{
"topic":"test4",
"partition":0,
"replicas":[
3,
2
],
"log_dirs":[
"any",
"any"
]
},
{
"topic":"test4",
"partition":2,
"replicas":[
2,
1
],
"log_dirs":[
"any",
"any"
]
},
{
"topic":"test4",
"partition":1,
"replicas":[
1,
3
],
"log_dirs":[
"any",
"any"
]
}
]
}
  1. 开始重分配
1
kafka-reassign-partitions.sh --zookeeper zookeeper:2181 --execute --reassignment-json-file test4_reassign.json

重分配结果如下
image.png