目录
消费者数据安全
说明:所有流程图均来自:Kafka 消费者数据安全策略流程图
一、消费方式
说明
-
1、Consumer 采用 Pull(拉取)模式从 Broker 中读取数据。
- Consumer 采用 Push(推送)模式,Broker 给 Consumer 推送消息的速率是由 Broker 决定的,很难适应消费速率不同的消费者。
- 它的目标是尽可能以最快速度传递消息,但是这样很容易造成 Consumer 来不及处理消息,典型的表现就是拒绝服务以及网络拥塞
-
2、而 Pull 模式则可以根据 Consumer 的消费能力以适当的速率消费消息
注意
- 1、Pull 模式不足之处是,如果 Kafka 没有数据,消费者可能会陷入循环中,一直返回空数据。
- 2、因为消费者从 Broker 主动拉取数据,需要维护一个长轮询,针对这一点, Kafka 的消费者在消费数据时会传入一个时长参数 timeout。
- 3、如果当前没有数据可供消费,Consumer 会等待一段时间之后再返回,这段时长即为timeout。
二、分区分配策略
概念
- 将分区的所有权从一个消费者移到另一个消费者称为
重新平衡(rebalance)
分区分配的时机
- 同一个 Consumer Group 内新增消费者
- 消费者离开当前所属的Consumer Group,包括shuts down 或 crashes
- 订阅的主题新增分区
Kafka 有三种分配策略:
- 一个是
RangeAssignor(默认)
,计算,字典序靠前的消费者会被多分配一个分区。 - 一个是
RoundRobinAssignor
,轮询分发。 - 一个是
StickyAssignor
(0.11.x版本开始引入)
1、RangeAssignor分配策略
-
策略的原理
原理
是按照消费者总数和分区总数进行整除运算
来获得一个跨度,然后将分区按照跨度进行平均分配,以保证分区尽可能均匀地分配给所有的消费者。
-
说明
- 对于每一个topic,RangeAssignor策略会将消费组内所有订阅这个topic的消费者按照名称的字典序排序,然后为每个消费者划分固定的分区范围,如果不够平均分配,那么字典序靠前的消费者会被多分配一个分区。
-
参数
- RangeAssignor策略对应的partition.assignment.strategy参数值为:
org.apache.kafka.clients.consumer.RangeAssignor
-
计算流程
- 1、 假设 n=一个
topic的分区数
/ 订阅此topic消费者数量
, - 2、m =
分区数%消费者数量
, - 3、 那么前 m个消费者每个分配n+1个分区,后面的(消费者数量-m)个消费者每个分配n个分区。
- 1、 假设 n=一个
-
实例
- 1、假设一个 topic 有 5 分区,订阅此topic 有 3 个消费者 C1、C2、C3,
- 2、那么每个消费者先分配 5 / 3 = 1 个分区, 5 % 3 =2,前两个消费者每人多得到一个分区。
- 3、此时各个消费则分配 topic 的分区如下:
C1 : 1 + 1个
C2 : 1 + 1个
C3 : 1 个
-
常见分配场景
-
1 consumer 订阅 1 topic ( 5 partition )
-
2 consumer 订阅 1 topic ( 5 partition )
-
3 consumer 订阅 1 topic ( 5 partition )
-
6 consumer 订阅 1 topic ( 5 partition )
-
消费组中的消费者个数如果超过 topic 的分区,那么就会有消费者消费不到数据
-
缺陷
- 可以明显的看到这样的分配并不均匀,如果将类似的情形扩大,有可能会出现部分消费者过载的情况
- 可以明显的看到这样的分配并不均匀,如果将类似的情形扩大,有可能会出现部分消费者过载的情况
-
2、RoundRobinAssignor分配策略
-
策略的原理
原理
是将消费组内所有消费者以及消费者所订阅的所有topic的partition按照字典序排序,然后通过轮询消费者方式逐个将分区分配给每个消费者
-
参数
- RoundRobinAssignor策略对应的partition.assignment.strategy参数值为:
org.apache.kafka.clients.consumer.RoundRobinAssignor
-
消费者订阅相同 Topic
- 如果同一个消费组内所有的消费者的订阅信息都是相同的,那么RoundRobinAssignor策略的分区分配会均匀
的。
-
消费者订阅不同 Topic
- 如果同一个消费组内的消费者所订阅的Topic 是不相同的,那么在执行分区分配的时候就不是完全的轮询分配,有可能会导致分区
分配的不均匀
。 - 如果某个消费者没有订阅消费组内的某个topic,那么在分配分区的时候此消费者将分配不到这个topic的任何分区。
- 如果同一个消费组内的消费者所订阅的Topic 是不相同的,那么在执行分区分配的时候就不是完全的轮询分配,有可能会导致分区
3、StickyAssignor分配策略
-
说明
- StickyAssignor策略,“sticky”这个单词可以翻译为“粘性的”,Kafka从0.11.x版本开始引入这种分配策略
-
两个主要目的
- 1、 分区的分配要尽可能的均匀;
- 2、 分区的分配尽可能的与上次分配的保持相同。
- 当两者发生冲突时,第一个目标
优先于
第二个目标
-
消费者订阅相同 Topic
-
实例
- 1、假设消费组内有3个消费者:C1、C2和C3,它们都订阅了4个主题:t1、t2、t3、t4,并且每个主题有2个分区
- 2、也就是说整个消费组订阅了t1p1、t1p2、t2p1、t2p2、t3p1、t3p2、t4p1、t4p2这8个分区。
-
情景
- 假设此时
消费者C1脱离
了消费组,那么消费组就会执行再平衡操作,进而消费分区会重新分配
- 假设此时
-
策略一
RoundRobinAssignor策略
-
策略二
StickyAssignor策略
-
-
消费者订阅不同 Topic
-
实例
- 1、同样消费组内有3个消费者:C1、C2和C3,集群中有3个主题:t1、t2和t3,
- 2、这3个主题分别有1、2、3个分区,也就是说集群中有t1p1、t2p1、t2p2、t3p1、t3p2、t3p3这6个分区。
- 3、消费者C1订阅了主题t1,消费者C2订阅了主题t1和t2,消费者C3订阅了主题t1、t2和t3。
-
策略一
RoundRobinAssignor策略
-
策略二
StickyAssignor策略
-
情景一
消费者脱离消费组
的情况 RoundRobin
-
情景二
消费者脱离消费组
的情况 Sticky
-
结果
- 从结果上看
StickyAssignor策略
比另外两者分配策略而言显得更加的优异
,这个策略的代码实现也是异常复杂,如果大家在一个 group 里面,不同的 Consumer 订阅不同的 topic, 那么设置Sticky分配策略还是很有必要的。
底线。。。。。