一 kafka的消费策略
1
、一个
consumer group
中有多个
consumer
组成,一个
topic
有多个
partition
组成,现在的问题是,
到底由哪个
consumer
来消费哪个partition的数据
。
2
、
Kafka
有四种主流的分区分配策略:
Range
、
RoundRobin
、
Sticky
、
CooperativeSticky
。
可以通过配置参数
partition.assignment.strategy
,修改分区的分配策略。默认策略是
Range + CooperativeSticky
。
Kafka
可以同时使用 多个分区分配策略。
3.策略判断参数
4.执行流程
1. 每个consumer都 发送JoinGroup请求
2.选出一个 consumer作为
leader
3.把要消费的
topic
情况 发送给leader
消费者
4.
leader
会负 责制定消费方案
5.
把消费方案发给
coordinator
6.
Coordinator
就把消费 方案下发给各个consumer
7.每个消费者都会和
coordinator
保持心跳(
默认
3s
),一旦超时 session.timeout.ms=
45s
),该消费者会被移除,并触发再平衡;或者消费者处理消息的过长(max.poll.interval.ms
5
分钟),也会触发再
平衡
二 Range分区策略
2.1 range分区策略
Range
是对每个
topic
而言的。 首先对同一个 topic
里面的
分区按照序号进行排序
,并
对
消费者按照字母顺序进行排序
。
假如现在有
7
个分区,
3
个消费者,排序后的分区将会 是0,1,2,3,4,5,6
;消费者排序完之后将会是
C0,C1,C2
。 例如,7/3 = 2
余
1
,除不尽,那么 消费者
C0
便会多 消费 1
个分区。
8/3=2
余
2
,除不尽,那么
C0
和
C1
分别多 消费一个。 通过
partitions
数
/consumer
数
来决定每个消费者应该
消费几个分区。
如果除不尽,那么前面几个消费者将会多 消费 1
个分区。
分区分配策略之
Range
注意:
如果只是针对
1
个
topic
而言,
C0
消费者多消费
1 个分区影响不是很大。但是如果有 N
多个
topic
,那么针对每 个 topic
,消费者
C0
都将多消费
1
个分区,
topic
越多,
C0
消 费的分区会比其他消费者明显多消费 N
个分区。
容易产生数据倾斜!
2.2 案例分析
1.修改主题 first 为 7 个分区。注意:分区数可以增加,但是不能减少。
bin/kafka-topics.sh --bootstrap-server hadoop102:9092
--alter
--topic first --partitions 7
2.复制 CustomConsumer 类,创建 CustomConsumer2。这样可以由三个消费者
CustomConsumer
、
CustomConsumer1
、
CustomConsumer2
组成消费者组,组名都为“
test
”,
同时启动
3
个消费者。
3.
启动
CustomProducer
生产者,发送
500
条消息,随机发送到不同的分区。
说明:
Kafka
默认的分区分配策略就是
Range + CooperativeSticky
,所以不需要修改策
略
4.
观看
3
个消费者分别消费哪些分区的数据。
0号消费者
1号消费者
2号消费者
分析:
1).停止掉
0
号消费者,快速重新发送消息, 然后观看结果(45s 以内,越快越好)。
1
号消费者:消费到
3
、
4
号分区数据。
2
号消费者:消费到
5
、
6
号分区数据。
0
号消费者的任务会
整体被分配
到
1
号消费者或者
2
号消费者。
说明:
0
号消费者挂掉后,消费者组需要按照超时时间
45s
来判断它是否退出,所以需
要等待,时间到了
45s
后,判断它真的退出就会把任务分配给其他
broker
执行。
2)45s 以后,再次重新发送消息观看结果。
1
号消费者:消费到
0
、
1
、
2
、
3
号分区数据。
2
号消费者:消费到
4
、
5
、
6
号分区数据。
说明:消费者
0
已经被踢出消费者组,所以重新按照
range
方式分配。
三 RoundRobin分区策略
3.1 分区策略
RoundRobin
针对集群中
所有
Topic
而言
。 RoundRobin 轮询分区策略,是把
所有的
partition
和所有的 consumer 都列出来
,然后
按照
hashcode
进行排序
,最后 通过
轮询算法
来分配
partition
给到各个消费者。
3.2 案例
1.修改之前的3个消费者,消费策略:依次在 CustomConsumer、CustomConsumer1、CustomConsumer2 三个消费者代 码中修改分区分配策略为 RoundRobin。
2.重启 3 个消费者,重复发送消息的步骤,观看分区结果。
消费者0:
消费者1:
消费者2:
分析:
1)停止掉
0
号消费者,快速重新发送消息,然后观看结果(45s 以内,越快越好)。
1
号消费者:消费到
2
、
5
号分区数据
2
号消费者:消费到 3
、6、
0
号分区数据
0
号消费者的任务会
按照
RoundRobin
的方式,把数据轮询分成 1
、4
号分区数据,
分别由
1
号消费者或者
2
号消费者消费。
说明:
0
号消费者挂掉后,消费者组需要按照超时时间
45s
来判断它是否退出,所以需
要等待,时间到了
45s
后,判断它真的退出就会把任务分配给其他
broker
执行
2)
45s
以后,再次重新发送消息观看结果。
1
号消费者:消费到
0
、
2
、
4
、
6
号分区数据
2
号消费者:消费到
1
、
3
、
5
号分区数据
说明:消费者
0
已经被踢出消费者组,所以重新按照
RoundRobin
方式分配。
四 Sticky 以及再平衡
4.1 粘性分区
粘性分区定义:
可以理解为分配的结果带有“粘性的”。即在执行一次新的分配之前, 考虑上一次分配的结果,尽量少的调整分配的变动,可以节省大量的开销。
粘性分区是
Kafka
从
0.11.x
版本开始引入这种分配策略,
首先会尽量均衡的放置分区
到消费者上面
,在出现同一消费者组内消费者出现问题的时候,会
尽量保持原有分配的分
区不变化。
4.2 案例
设置主题为
first
,
7
个分区;准备
3
个消费者,采用粘性分区策略,并进行消费,观察
消费分配情况。然后再停止其中一个消费者,再次观察消费分配情况
1.修改分区分配策略为粘性。
注意:
3
个消费者都应该注释掉,之后重启
3
个消费者,如果出现报错,全部停止等 会再重启,或者修改为全新的消费者组。
2.使用同样的生产者发送 500 条消息。可以看到会尽量保持分区的个数近似划分分区
0号消费者
1号消费者
2号消费者
分析:
(
1
)停止掉
0
号消费者,快速重新发送消息,然后观看结果(45s 以内,越快越好)。
1
号消费者:消费到
2
、
5
、
3
号分区数据。
2
号消费者:消费到
4
、
6
号分区数据。
0
号消费者的任务会
按照粘性规则,尽可能均衡的随机分成
0
和
1
号分区数据,分别
由
1
号消费者或者
2
号消费者消费。
说明:
0
号消费者挂掉后,消费者组需要按照超时时间
45s
来判断它是否退出,所以需
要等待,时间到了
45s
后,判断它真的退出就会把任务分配给其他
broker
执行。
(2)45s
以后,再次重新发送消息观看结果
。
1
号消费者:消费到
2
、
3
、
5
号分区数据。
2
号消费者:消费到
0
、
1
、
4
、
6
号分区数据。
说明:消费者
0
已经被踢出消费者组,所以重新按照粘性方式分配。