kafka
容许通过配置 partition.assignment.strategy
来扭转生产组的分区策略。kafka
提供了以下几个分区策略
RangeAssignor
RoundRobinAssignor
StickyAssignor
默认应用的是 RangeAssignor
同时,kafka
也容许咱们自定义分区策略,只须要继承 AbstractPartitionAssignor
抽象类即可。
1、RangeAssignor
现假如有生产组 c1, c2
,均订阅 t0, t1
, 每个 topic
下均有 2 个分区 t0p0, t0p1, t1p0, t1p1
那么分区如下:
c1: t0p0, t1p0
c2: t0p1, t1p1
如果每个 topic
有 3 个分区,那么调配将会不平均
c1: t0p0, t0p1, t1p0, t1p1
c2: t0p2, t1p2
算法依照每个 topic
下的分区数,进行均分。
2、RoundRobinAssignor
将生产组按字典排序,而后轮询调配。
现假如有生产组 c1, c2
。均订阅 t0, t1
。每个 topic
下均有 3 个分区。
分区如下
c1: t0p0, t0p2, t1p1
c2: t0p1, t1p0, t1p2
现假如有生产组 c1, c2, c3
。其中 c1
订阅 t0
, c2
订阅 t1
, c3
订阅 t0, t1, t2
, t0
有 1 个分区 t0p0
, t1
有 2 个分区 t1p0
, t1p1
, t2
有 3 个分区 t2p0, t2p1, t2p3
分区如下
c1: t0
c2: t1p0
c3: t1p1, t2p0, t2p1, t2p3
3、StickyAssignor
该调配策略,遵循以下 2 个准则
- 分区的调配要尽可能平均
- 分区的调配要尽可能与上次调配的放弃雷同
两者发生冲突,第一个条件优先级大于第二个
现假如有生产组 c1, c2, c3
。均订阅 t0, t1
, 每个分区均有 3 个分区
分区如下
c1: t0p0, t1p0
c2: t0p1, t1p1
c3: t0p2, t1p2
能够看到,与 RoundRobinAssignor
算法类似。
再来看,不同生产组订阅的分区不统一时,会产生什么
现假如有生产组 c1, c2, c3
。其中 c1
订阅 t0
, c2
订阅 t1
, c3
订阅 t0, t1, t2
, t0
有 1 个分区 t0p0
, t1
有 2 个分区 t1p0
, t1p1
, t2
有 3 个分区 t2p0, t2p1, t2p3
分区如下
c1: t0p0
c2: t1p0, t1p1
c3: t2p0, t2p1, t2p3
这边贴一下 RoundRobinAssignor
算法的分区,进行比照
c1: t0p0
c2: t1p0
c3: t1p1, t2p0, t2p1, t2p3
能够看到 StickyAssignor
算法的调配比 RoundRobinAssignor
更优。就是 分区的调配要尽可能平均
再假如如果 c1 退出订阅,这个时候,分区调配会怎么样?
c2: t0p0, t1p0, t1p1
c3: t2p0, t2p1, t2p3
4、总结
RocketMQ
倡议 生产组只订阅一个 topic,在自己理论开发过程中也根本是如此。如果订阅多个 topic
,生产组将无奈失常工作。对于 kafka
而言,生产组能够订阅多个 topic
来说,的确是很灵便。