副本

如果 kafka 服务器只有 4 个节点,那么设置 kafka 的分区数大于服务器台数,在 kafka 底层如何分配存储副本呢?

测试

创建一个 16 分区,3 个副本的主题 second

1
kafka-topics.bat --bootstrap-server localhost:9092 --create --replication-factor 3 --partitions 16 --topic second

查看主题详情

1
kafka-topics.bat --bootstrap-server localhost:9092 --describe --topic second

结果展示

Topic: second TopicId: uoa0SNNlTrqHDYdKgxAxJw PartitionCount: 16 ReplicationFactor: 3 Configs: segment.bytes=1073741824
Topic: second Partition: 0 Leader: 2 Replicas: 2,3,1 Isr: 2,3,1
Topic: second Partition: 1 Leader: 3 Replicas: 3,1,0 Isr: 3,1,0
Topic: second Partition: 2 Leader: 1 Replicas: 1,0,2 Isr: 1,0,2
Topic: second Partition: 3 Leader: 0 Replicas: 0,2,3 Isr: 0,2,3

​ Topic: second Partition: 4 Leader: 2 Replicas: 2,1,0 Isr: 2,1,0
​ Topic: second Partition: 5 Leader: 3 Replicas: 3,0,2 Isr: 3,0,2
​ Topic: second Partition: 6 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3
​ Topic: second Partition: 7 Leader: 0 Replicas: 0,3,1 Isr: 0,3,1

​ Topic: second Partition: 8 Leader: 2 Replicas: 2,0,3 Isr: 2,0,3
​ Topic: second Partition: 9 Leader: 3 Replicas: 3,2,1 Isr: 3,2,1
​ Topic: second Partition: 10 Leader: 1 Replicas: 1,3,0 Isr: 1,3,0
​ Topic: second Partition: 11 Leader: 0 Replicas: 0,1,2 Isr: 0,1,2

​ Topic: second Partition: 12 Leader: 2 Replicas: 2,3,1 Isr: 2,3,1
​ Topic: second Partition: 13 Leader: 3 Replicas: 3,1,0 Isr: 3,1,0
​ Topic: second Partition: 14 Leader: 1 Replicas: 1,0,2 Isr: 1,0,2
​ Topic: second Partition: 15 Leader: 0 Replicas: 0,2,3 Isr: 0,2,3

结论

Leader 顺序是 2、3、1、0 ;那么对于每个每个分区的副本分布

第一轮:0 分区:2、3、1;1 分区:3、1、0(没有间隔)

第二轮:4 分区:2、1、0(间隔一个 3);5 分区:3、0、2(间隔一个 1)

第三轮:8 分区:2、0、3(间隔两个:3、1);9 分区:3、2、1(间隔两个:1、0)

第四轮:12 分区:2、3、1(间隔三个:3、1、0);13 分区:3、1、0(间隔三个:1、0、2)(也就是回到第一轮循环)

手动调整副本

1、需求

在生产环境中,每台服务器的配置和性能不一致,但是 Kafka 只会根据自己的代码规则创建对应的分区副本,就会导致个别服务器存储压力较大。所有需要手动调整分区副本的存储。

需求:创建一个新的 topic,4 个分区,两个副本,名称为 three。将该 topic 的所有副本都存储到 broker0 和 broker1 两台服务器

2、准备

创建一个新的 topic,名称为 three

1
kafka-topics.bat --bootstrap-server localhost:9092 --create --replication-factor 2 --partitions 4 --topic three

查看详情

1
kafka-topics.bat --bootstrap-server localhost:9092 --describe --topic three

Topic: three TopicId: CBhgHobMT1yuF5B7WT8nJw PartitionCount: 4 ReplicationFactor: 2 Configs: segment.bytes=1073741824
Topic: three Partition: 0 Leader: 3 Replicas: 3,1 Isr: 3,1
Topic: three Partition: 1 Leader: 1 Replicas: 1,0 Isr: 1,0
Topic: three Partition: 2 Leader: 0 Replicas: 0,2 Isr: 0,2
Topic: three Partition: 3 Leader: 2 Replicas: 2,3 Isr: 2,3

创建副本存储计划(所有副本都指定存储在 broker0、broker1 中)

新建文件:increase-replication-factor.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
{
"version": 1,
"partitions": [
{
"topic": "three",
"partition": 0,
"replicas": [0, 1]
},
{
"topic": "three",
"partition": 1,
"replicas": [0, 1]
},
{
"topic": "three",
"partition": 2,
"replicas": [1, 0]
},
{
"topic": "three",
"partition": 3,
"replicas": [1, 0]
}
]
}

3、执行

执行副本存储计划

1
kafka-reassign-partitions.bat --bootstrap-server localhost:9092 --reassignment-json-file increase-replication-factor.json --execute

4、验证

1
kafka-reassign-partitions.bat --bootstrap-server localhost:9092 --reassignment-json-file increase-replication-factor.json --verify

查看详情

1
kafka-topics.bat --bootstrap-server localhost:9092 --describe --topic three

Topic: three TopicId: CBhgHobMT1yuF5B7WT8nJw PartitionCount: 4 ReplicationFactor: 2 Configs: segment.bytes=1073741824
Topic: three Partition: 0 Leader: 1 Replicas: 0,1 Isr: 1,0
Topic: three Partition: 1 Leader: 1 Replicas: 0,1 Isr: 1,0
Topic: three Partition: 2 Leader: 0 Replicas: 1,0 Isr: 0,1
Topic: three Partition: 3 Leader: 1 Replicas: 1,0 Isr: 0,1

增加副本因子

1、需求

在生产环境当中,由于某个主题的重要等级需要提升,我们考虑增加副本。副本数的增加需要先制定计划,然后根据计划执行

2、准备

创建一个新的 topic,名称为 five,4 个分区,一个副本

1
kafka-topics.bat --bootstrap-server localhost:9092 --create --replication-factor 1 --partitions 4 --topic five

查看详情

1
kafka-topics.bat --bootstrap-server localhost:9092 --describe --topic five

Topic: five TopicId: USnONFVFSlCGmLg-sM5TWg PartitionCount: 4 ReplicationFactor: 1 Configs: segment.bytes=1073741824
Topic: five Partition: 0 Leader: 1 Replicas: 1 Isr: 1
Topic: five Partition: 1 Leader: 0 Replicas: 0 Isr: 0
Topic: five Partition: 2 Leader: 2 Replicas: 2 Isr: 2
Topic: five Partition: 3 Leader: 3 Replicas: 3 Isr: 3

创建副本存储计划(所有副本都指定存储在 broker0、broker1 、borker2、borker3 中)

修改上面的文件:increase-replication-factor.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
{
"version": 1,
"partitions": [
{
"topic": "five",
"partition": 0,
"replicas": [0, 1, 2, 3]
},
{
"topic": "five",
"partition": 1,
"replicas": [0, 1, 2, 3]
},
{
"topic": "five",
"partition": 2,
"replicas": [0, 1, 2, 3]
},
{
"topic": "five",
"partition": 3,
"replicas": [0, 1, 2, 3]
}
]
}

3、执行

执行副本存储计划

1
kafka-reassign-partitions.bat --bootstrap-server localhost:9092 --reassignment-json-file increase-replication-factor.json --execute

4、验证

1
kafka-reassign-partitions.bat --bootstrap-server localhost:9092 --reassignment-json-file increase-replication-factor.json --verify

查看详情

1
kafka-topics.bat --bootstrap-server localhost:9092 --describe --topic five

Topic: five TopicId: USnONFVFSlCGmLg-sM5TWg PartitionCount: 4 ReplicationFactor: 4 Configs: segment.bytes=1073741824
Topic: five Partition: 0 Leader: 1 Replicas: 0,1,2,3 Isr: 1,3,2,0
Topic: five Partition: 1 Leader: 0 Replicas: 0,1,2,3 Isr: 0,3,2,1
Topic: five Partition: 2 Leader: 2 Replicas: 0,1,2,3 Isr: 2,3,1,0
Topic: five Partition: 3 Leader: 3 Replicas: 0,1,2,3 Isr: 3,0,1,2

分区平衡

正常情况下,Kafka 本身会自动把 Leader Partition 均匀分散在各个机器上,来保证每台机器的读写吞吐量都是均匀的。但是如果某些 broker 宕机,会导致 Leader Partition 过于集中在其他少部分几台 broker 上,这会导致少数几台 broker 的读写请求压力过高,其他宕机的 broker 重启之后都是 follower partition ,读写请求很低,造成集群负载不均

参数名称描述
auto.leader.rebalance.enable默认是 true。自动 Leader Partition 平衡。生产环境中,leader 重新选举的代价比较大,可能会带来性能影响,建议设置为 false 关闭,或者将默认 10%的比例调整大一些。
leader.imbalance.per.broker.percentage默认是 10%。 每个 broker 允许的不平衡的 leader 的比率。如果每个 broker 超过了这个值,控制器会触发 leader 的平衡。
leader.imbalance.check.interval.seconds默认值 300 秒。检查 leader 负载是否平衡的间隔时间。

不平衡比率的计算

创建了一个主题 four

Topic: four TopicId: 6e7RLpaxSBuBSWRfaw-1RQ PartitionCount: 4 ReplicationFactor: 4 Configs: segment.bytes=1073741824
Topic: four Partition: 0 Leader: 1 Replicas: 1,0,2,3 Isr: 1,0,2,3
Topic: four Partition: 1 Leader: 0 Replicas: 0,2,3,1 Isr: 0,2,3,1
Topic: four Partition: 2 Leader: 2 Replicas: 2,3,1,0 Isr: 2,3,1,0
Topic: four Partition: 3 Leader: 3 Replicas: 3,1,0,2 Isr: 3,1,0,2

borker1 和 broker2 宕机后恢复

Topic: four TopicId: 6e7RLpaxSBuBSWRfaw-1RQ PartitionCount: 4 ReplicationFactor: 4 Configs: segment.bytes=1073741824
Topic: four Partition: 0 Leader: 0 Replicas: 1,0,2,3 Isr: 0,3,1,2
Topic: four Partition: 1 Leader: 0 Replicas: 0,2,3,1 Isr: 0,3,1,2
Topic: four Partition: 2 Leader: 3 Replicas: 2,3,1,0 Isr: 3,0,1,2
Topic: four Partition: 3 Leader: 3 Replicas: 3,1,0,2 Isr: 3,0,1,2

针对 borker1 节点(1,0,2,3),分区 0 的 AR 优先副本是 1 节点,但是 1 节点却不是 Leader 节点,所以不平衡数为 1,AR 副本总数是 4,所以 broker0 节点不平衡率为 1/4>10%,需要再平衡

针对 borker0 节点(0,2,3,1),分区 1 的 AR 优先副本是 0 节点,平衡

针对 borker2 节点(2,3,1,0),分区 2 的 AR 优先副本是 2 节点,但是 2 节点却不是 Leader 节点,所以不平衡数为 1,AR 副本总数是 4,所以 broker2 节点不平衡率为 1/4>10%,需要再平衡

针对 borker3 节点(3,1,0,2),分区 3 的 AR 优先副本是 3 节点,平衡