diff --git a/mq/kafka/kafka-尚硅谷.md b/mq/kafka/kafka-尚硅谷.md index 9f3fc7f..97c57de 100644 --- a/mq/kafka/kafka-尚硅谷.md +++ b/mq/kafka/kafka-尚硅谷.md @@ -27,6 +27,13 @@ kafka将一个topic分为了多个分区,用于分布式存储数据。而每 > > 在一个consume group中,每个消费者实例都负责某一topic中相应的分区,每个特定分区只有一个消费者实例负责。 + +> #### 消费者订阅 +> 消费者的订阅操作是在消费者实例中调用的,在同一消费者组中,**不同消费者实例可以订阅不同的topic集合**。topic的分区只会在订阅了该topic的实例之间进行分配。 +> +> 例如存在消费者实例c1,c2,c3, 其中c1订阅了t1,c2订阅了t1和t2,c3订阅了t1, t2, t3, 那么t1的分区将会在c1, c2, c3之间进行发呢配,t2的分区只会在c2和c3之间进行分配,t3的分区只会被分配给c3 + + #### zookeeper zookeeper作为注册中心,用于记录存在多个kafka实例时,当前已上线且状态正常的kafka实例,以及各个分区leader实例的信息 @@ -325,5 +332,39 @@ kafka采用的是拉取模式来进行消费,因为拉取模式可以很好的 > poll方法调用在没有可用的消息集合时,会发送fetch请求从broker拉取数据 +##### 分区分配和再平衡 +一个消费者组中含有多个消费者实例,而一个topic会包含多个分区,需要将topic中的分区在消费者组中的多个消费者实例之间进行分配。 + +kafka中包含如下分区策略: +- range +- RoundRobin +- Sticky +- CooperativeSticky + +kafka中的分区策略通过`partition.assignment.strategy`参数来进行配置,kafka可以通过使用多个分区分配策略,多个策略会进行叠加。默认情况下,kafka采用`Range + CooperativeSticky`的策略来进行分区分配。 + +> #### Range策略及再平衡 +> range策略会针对每个topic进行分配。如果一个topic中含有n个分区,消费者组中含有m个消费者实例,那么每个消费者实例将会分配到n/m(整除)个分区,多出来的n%m个分区将会被分配给实例名称靠前的n%m个实例。 +> +> range策略将会有如下弊端,如果每个topic都无法对消费者实例整除,那么剩余的分区都会被分配给排序靠前的消费者实例,这样会造成分区在消费者实例之间分配的不平衡,排序靠前的消费者实例会负担更多的分区 +> +> 在使用range策略时,如果某台消费者实例宕机,那么在宕机超过限定时间(45s内没有向broker coordinator发送心跳包),会将topic分区重新在消费组中的剩余实例之间进行再分配(完全重新生成分配方案,排序靠前的消费者实例在分区数量无法整除实例个数时,负担更多的分区消费) + +> #### RoundRobin +> RoundRobin策略针对所有消费者组订阅的所有topic中的分区,会将所有分区根据hashcode进行排序,并且按轮询的顺序分配给消费者实例。例如,第一个分区分配给第一个消费者实例,第二个分区分配给第二个实例...第m+1个分区再次分配给第一个实例(实例总数为m)。RoundRobin将所有分区在所有消费者实例之间进行了平衡,而不像range一样只是针对单个topic中的分区。 +> +> 在使用RoundRobin策略时,如果消费者中某一实例宕机,超过超时时间后,分区同样会在剩余的消费者实例之间进行重新分配。 + +> #### Sticky +> Sticky策略同样是针对所有topic的分区,类似于RoundRobin。但是,不同于RoundRobin的轮询,Sticky在分配策略时会遵循如下原则: +> - Sticky策略会尽可能均匀的在不同消费者实例之间分配分区 +> - 如果因为某些原因(例如实例宕机)导致需要进行分区的重新分配,Sticky会尽可能的保证存活实例上已经产生的分区分配不被改变,并再次基础上令所有分区在实例间的分配尽量均衡 +> +> 在使用Sticky策略时,即使某台实例宕机,再平衡后存活实例被分配的分区仍然不会变,只是会将宕机实例负责的分区在存活实例之间尽可能均衡的分配 + + + + +