2021金三银四面试季!Kafka分区管理(优先副本的选举

现在我们需要将原先分布在broker 1-3节点上的分区重新分布到broker 1-4节点上,借助kafka-reassign-partitions.sh工具生成reassign plan,不过我们先得按照要求定义一个文件,里面说明哪些topic需要重新分区,文件内容如下:

itcast@Server-node:/mnt/d/kafka-cluster/kafka-1$ cat reassign.json {
	"topics":[{"topic":"heima-par"}], 
	"version":1 
}

然后使用 kafka-reassign-partitions.sh 工具生成reassign plan

然后执行脚本 bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --topics-to -move-json-file reassign.json --broker-list "0,1,2,3" --generate

itcast@Server-node:/mnt/d/kafka-cluster/kafka-1$ bin/kafka-reassign- 
partitions.sh --zookeeper localhost:2181 --topics-to 
-move-json-file reassign.json --broker-list "0,1,2,3" --generate 
Current partition replica assignment 
{"version":1,"partitions":[{"topic":"heima-par","partition":2,"replicas": [1,0,2],"log_dirs":["any","any","any"]},
{"topic":"heima- par","partition":1,"replicas":[0,2,1],"log_dirs":["any","any","any"]}, 
{"topic":"heima-par","partition":0,"replicas":[2,1,0],"log_dirs": ["any","any","any"]},
{"topic":"heima-par","partition":3,"replicas": [2,1,0],"log_dirs":["any","any","any"]}]} 

Proposed partition reassignment configuration 
{"version":1,"partitions":[{"topic":"heima-par","partition":0,"replicas": [1,2,3],"log_dirs":["any","any","any"]},
{"topic":"heima- par","partition":2,"replicas":[3,0,1],"log_dirs":["any","any","any"]}, 
{"topic":"heima-par","partition":1,"replicas":[2,3,0],"log_dirs": ["any","any","any"]},
{"topic":"heima-par","partition":3,"replicas": [0,1,2],"log_dirs":["any","any","any"]}]}

上面命令中

--generate 表示指定类型参数

--topics-to-move-json-file 指定分区重分配对应的主题清单路径

注意:
命令输入两个Json字符串,第一个JSON内容为当前的分区副本分配情况,第二个为重新分配的候选方案,注意这里只是生成一份可行性的方案,并没有真正执行重分配的动作。

我们将第二个JSON内容保存到名为result.json文件里面(文件名不重要,文件格式也不一定要以json为结尾,只要保证内容是json即可),然后执行这些reassign plan

重新分配JSON文件

{ 
	"version": 1, 
	"partitions": [ { 
		"topic": "heima-par", 
		"partition": 0, 
		"replicas": [ 1,2,3 ],
		"log_dirs": [ "any", "any", "any" ] 
	},{ 
		"topic": "heima-par", 
		"partition": 2, 
		"replicas": [ 3,0,1 ],
		"log_dirs": [ "any", "any", "any" ] 
	},{ 
		"topic": "heima-par", 
		"partition": 1, 
		"replicas": [ 2,3,0 ],
		"log_dirs": [ "any", "any", "any" ] 
	},{ 
		"topic": "heima-par", 
		"partition": 3, 
		"replicas": [ 0,1,2 ],
		"log_dirs": [ "any", "any", "any" ]
	} 
	] 
}

执行分配策略

itcast@Server-node:/mnt/d/kafka-cluster/kafka-1$ bin/kafka-reassign- 
partitions.sh --zookeeper localhost:2181 --reassignm 
ent-json-file result.json --execute 
Current partition replica assignment 

{"version":1,"partitions":[{"topic":"heima-par","partition":2,"replicas": [1,0,2],"log_dirs":["any","any","any"]},
{"topic":"heima- par","partition":1,"replicas":[0,2,1],"log_dirs":["any","any","any"]}, 
{"topic":"heima-par","partition":0,"replicas":[2,1,0],"log_dirs": ["any","any","any"]},
{"topic":"heima-par","partition":3,"replicas": [2,1,0],"log_dirs":["any","any","any"]}]} 
Save this to use as the --reassignment-json-file option during rollback 
Successfully started reassignment of partitions.

查看分区重新分配的进度:

itcast@Server-node:/mnt/d/kafka-cluster/kafka-1$ bin/kafka-reassign- 
partitions.sh --zookeeper localhost:2181 --reassignment-json-file result.json -- 
verify 
Status of partition reassignment: 
Reassignment of partition heima-par-3 completed successfully 
Reassignment of partition heima-par-0 is still in progress 
Reassignment of partition heima-par-2 is still in progress 
Reassignment of partition heima-par-1 is still in progress

从上面信息可以看出 heima-par-3已经完成,其他三个正在进行中。

四、修改副本因子

场景

实际项目中我们可能在创建topic时没有设置好正确的replication-factor,导致kafka集群虽然是高可用的,但是该topic在有broker宕机时,可能发生无法使用的情况。topic一旦使用又不能轻易删除重建,因此动态增加副本因子就成为最终的选择。

说明:kafka 1.0版本配置文件默认没有default.replication.factor=x, 因此如果创建topic时,不指定– replication-factor 想, 默认副本因子为1. 我们可以在自己的server.properties中配置上常用的副本因子,省去手动调整。例如设置default.replication.factor=3

首先我们配置topic的副本,保存为json文件

{ 
	"version":1, 
	"partitions":[ 
		{"topic":"heima","partition":0,"replicas":[0,1,2]}, 
		{"topic":"heima","partition":1,"replicas":[0,1,2]}, 
		{"topic":"heima","partition":2,"replicas":[0,1,2]} 
	] 
}

然后执行脚本 bin/kafka-reassign-partitions.sh --zookeeper localhost:2181 --reassignment-json-file replication-factor.json --execute

itcast@Server-node:/mnt/d/kafka_2.12-2.2.1$ bin/kafka-reassign-partitions.sh -- 
zookeeper localhost:2181 --reassignment-json-file replication-factor.json -- 
execute 
Current partition replica assignment 

{"version":1,"partitions":[{"topic":"topic0703","partition":1,"replicas": [1,0],"log_dirs":["any","any"]},
{"topic":"topic0703","partition":0,"replicas": [0,1],"log_dirs":["any","any"]},
{"topic":"topic0703","partition":2,"replicas": [2,0],"log_dirs":["any","any"]}]} 

Save this to use as the --reassignment-json-file option during rollback 
Successfully started reassignment of partitions.

验证

itcast@Server-node:/mnt/d/kafka_2.12-2.2.1$ bin/kafka-topics.sh --describe -- 
zookeeper localhost:2181 --topic topic0703 
Topic:topic0703 PartitionCount:3 	ReplicationFactor:3 	Configs: 
Topic: topic0703 	Partition: 0 	Leader: 0 	Replicas: 0,1,2 Isr: 0 
Topic: topic0703 	Partition: 1 	Leader: 1 	Replicas: 0,1,2 Isr: 1,0 
Topic: topic0703 	Partition: 2 	Leader: 2 	Replicas: 0,1,2 Isr: 2,0

五、分区分配策略

按照Kafka默认的消费逻辑设定,一个分区只能被同一个消费组(ConsumerGroup)内的一个消费者消费。假设目前某消费组内只有一个消费者C0,订阅了一个topic,这个topic包含7个分区,也就是说这个消费者C0订阅了7个分区,参考下图

image
此时消费组内又加入了一个新的消费者C1,按照既定的逻辑需要将原来消费者C0的部分分区分配给消费者C1消费,情形上图(2),消费者C0和C1各自负责消费所分配到的分区,相互之间并无实质性的干扰。

接着消费组内又加入了一个新的消费者C2,如此消费者C0、C1和C2按照上图(3)中的方式各自负责消费所分配到的分区。

如果消费者过多,出现了消费者的数量大于分区的数量的情况,就会有消费者分配不到任何分区。参考下图,一共有8个消费者,7个分区,那么最后的消费者C7由于分配不到任何分区进而就无法消费任何消息。
image
上面各个示例中的整套逻辑是按照Kafka中默认的分区分配策略来实施的。Kafka提供了消费者客户端参数partition.assignment.strategy用来设置消费者与订阅主题之间的分区分配策略。默认情况下,此参数的值为:org.apache.kafka.clients.consumer.RangeAssignor,即采用RangeAssignor分配策略。除此之外,Kafka中还提供了另外两种分配策略: RoundRobinAssignorStickyAssignor。消费者客户端参数partition.asssignment.strategy可以配置多个分配策略,彼此之间以逗号分隔。

1.RangeAssignor分配策略

参考源码:org.apache.kafka.clients.consumer.RangeAssignor

RangeAssignor策略 的原理是 按照消费者总数和分区总数进行整除运算来获得一个跨度,然后将分区按照跨度进行平均分配,以保证分区尽可能均匀地分配给所有的消费者。 对于每一个topic, RangeAssignor策略会将消费组内所有订阅这个topic的消费者按照名称的字典序排序,然后为每个消费者划分固定的分区范围,如果不够平均分配,那么字典序靠前的消费者会被多分配一个分区。

假设n=分区数/消费者数量,m=分区数%消费者数量,那么前m个消费者每个分配n+1个分区,后面的(消费者数量-m)个消费者每个分配n个分区。

假设消费组内有2个消费者C0和C1,都订阅了主题t0和t1,并且每个主题都有4个分区,那么所订阅的所有分区可以标识为:t0p0、t0p1、t0p2、t0p3、t1p0、t1p1、t1p2、t1p3。最终的分配结果为:

消费者C0:t0p0、t0p1、t1p0、t1p1 
消费者C1:t0p2、t0p3、t1p2、t1p3

假设上面例子中2个主题都只有3个分区,那么所订阅的所有分区可以标识为:t0p0、t0p1、t0p2、t1p0、t1p1、t1p2。最终的分配结果为:

消费者C0:t0p0、t0p1、t1p0、t1p1 
消费者C1:t0p2、t1p2

可以明显的看到这样的分配并不均匀,如果将类似的情形扩大,有可能会出现部分消费者过载的情况。

2.RoundRobinAssignor分配策略

参考源码:org.apache.kafka.clients.consumer.RoundRobinAssignor

RoundRobinAssignor策略 的原理是将消费组内所有消费者以及消费者所订阅的所有topic的partition按照字典序排序,然后通过轮询方式逐个将分区以此分配给每个消费者。 RoundRobinAssignor策略对应的partition.assignment.strategy参数值为:org.apache.kafka.clients.consumer.RoundRobinAssignor

假设消费组中有2个消费者C0和C1,都订阅了主题t0和t1,并且每个主题都有3个分区,那么所订阅的所有分区可以标识为:t0p0、t0p1、t0p2、t1p0、t1p1、t1p2。最终的分配结果为:

消费者C0:t0p0、t0p2、t1p1 
消费者C1:t0p1、t1p0、t1p2

如果同一个消费组内的消费者所订阅的信息是不相同的,那么在执行分区分配的时候就不是完全的轮询分配,有可能会导致分区分配的不均匀。如果某个消费者没有订阅消费组内的某个topic,那么在分配分区的时候此消费者将分配不到这个topic的任何分区。

假设消费组内有3个消费者C0、C1和C2,它们共订阅了3个主题:t0、t1、t2,这3个主题分别有1、2、 3个分区,即整个消费组订阅了t0p0、t1p0、t1p1、t2p0、t2p1、t2p2这6个分区。具体而言,消费者C0订阅的是主题t0,消费者C1订阅的是主题t0和t1,消费者C2订阅的是主题t0、t1和t2,那么最终的分配结果为:

消费者C0:t0p0 
消费者C1:t1p0 
消费者C2:t1p1、t2p0、t2p1、t2p2

可以看到RoundRobinAssignor策略也不是十分完美,这样分配其实并不是最优解,因为完全可以将分区t1p1分配给消费者C1。

总结

一般像这样的大企业都有好几轮面试,所以自己一定要花点时间去收集整理一下公司的背景,公司的企业文化,俗话说「知己知彼百战不殆」,不要盲目的去面试,还有很多人关心怎么去跟HR谈薪资。

这边给大家一个建议,如果你的理想薪资是30K,你完全可以跟HR谈33~35K,而不是一下子就把自己的底牌暴露了出来,不过肯定不能说的这么直接,比如原来你的公司是25K,你可以跟HR讲原来的薪资是多少,你们这边能给到我的是多少?你说我这边希望可以有一个20%涨薪。

最后再说几句关于招聘平台的,总之,简历投递给公司之前,请确认下这家公司到底咋样,先去百度了解下,别被坑了,每个平台都有一些居心不良的广告党等着你上钩,千万别上当!!!

提供【免费】的Java架构学习资料,学习技术内容包含有:Spring,Dubbo,MyBatis, RPC, 源码分析,高并发、高性能、分布式,性能优化,微服务 高级架构开发等等。

Java全套进阶资料点这里免费领取

还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书。
C, 源码分析,高并发、高性能、分布式,性能优化,微服务 高级架构开发等等。

Java全套进阶资料点这里免费领取

还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值