kafka consumer配置拉取速度慢_Kafka分区分配策略(Partition Assignment Strategy)
眾所周知,Apache Kafka是基于生產(chǎn)者和消費者模型作為開源的分布式發(fā)布訂閱消息系統(tǒng)(當(dāng)然,目前Kafka定位于an open-source distributed event streaming platform),由Scala和Java編寫。
Kafka提供了類似于JMS的特性,但設(shè)計上又有很大區(qū)別,它不是JMS規(guī)范的實現(xiàn),如Kafka允許多個消費者主動拉取數(shù)據(jù),而在JMS中只有點對點模式消費者才會主動拉取數(shù)據(jù)。
Kafka producer在向Kafka集群發(fā)送消息時,需要指定topic,Kafka根據(jù)topic對消息進行歸類(邏輯劃分),而一個topic通常會有多個partition分區(qū),落到磁盤上就是多個partition目錄。
Kafka consumer為了及時消費消息,會以Consumer Group(消費組)的形式,啟動多個consumer消費消息。不同的消費組在消費消息時彼此互不影響,同一個消費組的consumer協(xié)調(diào)在一起消費訂閱的topic所有分區(qū)消息。這就引申一個問題:消費組中的consumer是如何確定自己該消費哪些分區(qū)的數(shù)據(jù)的?
Kafka提供了多種分區(qū)策略如RoundRobin(輪詢)、Range(按范圍),可通過參數(shù)partition.assignment.strategy進行配置。
一般情況下,在topic和消費組不發(fā)生變化,Kafka會根據(jù)topic分區(qū)、消費組情況等確定分區(qū)策略,但是當(dāng)發(fā)生以下情況時,會觸發(fā)Kafka的分區(qū)重分配:
1. Consumer Group中的consumer發(fā)生了新增或者減少
2. Consumer Group訂閱的topic分區(qū)發(fā)生變化如新增分區(qū)
本文通過下面的場景,來分別闡述Kafka主要的分配策略RoundRobin和Range:
Range Strategy
Range策略是針對topic而言的,在進行分區(qū)分配時,為了盡可能保證所有consumer均勻的消費分區(qū),會對同一個topic中的partition按照序號排序,并對consumer按照字典順序排序。
然后為每個consumer劃分固定的分區(qū)范圍,如果不夠平均分配,那么排序靠前的消費者會被多分配分區(qū)。具體就是將partition的個數(shù)除于consumer線程數(shù)來決定每個consumer線程消費幾個分區(qū)。如果除不盡,那么前面幾個消費者線程將會多分配分區(qū)。
通過下面公式更直觀:
假設(shè)n = 分區(qū)數(shù) / 消費者數(shù)量,m = 分區(qū)數(shù) % 消費者線程數(shù)量,那么前m個消費者每個分配n+1個分區(qū),后面的(消費者線程數(shù)量 - m)個消費者每個分配n個分區(qū)。
舉個例子:
一個消費組CG1中有C0和C1兩個consumer,消費Kafka中的主題t1。t1的分區(qū)數(shù)為10,并且C1的num.streams為1,C2的num.streams為2。
經(jīng)過排序后,分區(qū)為:0, 1, 2, 3, 4, 5, 6, 7, 8, 9;CG1中消費者線程為C0-0、C1-0、C1-1。然后因為 10除3除不盡,那么消費者線程C0-0將會多分配分區(qū),所以分區(qū)分配之后結(jié)果如下:
C0-0 將消費0、1、2、3分區(qū) C1-0 將消費4、5、6分區(qū) C1-1 將消費7、8、9分區(qū)當(dāng)存在有2個Kafka topic(t1和t2),它們都有有10個partition,那么最后分區(qū)結(jié)果為:
C0-0 將消費t1主題的0、1、2、3分區(qū)以及t2主題的0、1、2、3分區(qū) C1-0 將消費t1主題的4、5、6分區(qū)以及t2主題的4、5、6分區(qū) C2-1 將消費t1主題的7、8、9分區(qū)以及t2主題的7、8、9分區(qū)如上場景,隨著topic的增多,那么針對每個topic,消費者C0-0都將多消費1個分區(qū),topic越多比如為N個,C0-0消費的分區(qū)會比其他消費者明顯多消費N個分區(qū)。
可以明顯的看到這樣的分配并不均勻,如果將類似的情形擴大,有可能會出現(xiàn)部分消費者過載的情況,這就是Range分區(qū)策略的一個很明顯的弊端。
RoundRobin Strategy
RoundRobin策略的工作原理:將所有topic的partition組成TopicAndPartition列表,然后對TopicAndPartition列表按照hashCode進行排序:
val allTopicPartitions = ctx.partitionsForTopic.flatMap { case(topic, partitions) =>info("Consumer %s rebalancing the following partitions for topic %s: %s".format(ctx.consumerId, topic, partitions))partitions.map(partition => {TopicAndPartition(topic, partition)}) }.toSeq.sortWith((topicPartition1, topicPartition2) => {/** Randomize the order by taking the hashcode to reduce the likelihood of all partitions of a given topic ending* up on one consumer (if it has a high enough stream count).*/topicPartition1.toString.hashCode < topicPartition2.toString.hashCode })最后按照RoundRobin風(fēng)格將分區(qū)分別分配給不同的消費者。
使用RoundRobin策略必須滿足以下條件:
1.同一個Consumer Group里面的所有consumer的num.streams必須相等
2.每個consumer訂閱的topic必須相同
假設(shè)消費組CG1中有C0和C1兩個consumer的num.streams都為2。按照hashCode排序完的topic-partition組依次為t1-5, t1-3, t1-0, t1-8, t1-2, t1-1, t1-4, t1-7, t1-6, t1-9,我們的消費者排序為C0-0, C0-1, C1-0, C1-1,最后分區(qū)分配的結(jié)果為:
C0-0將消費t1-5、t1-2、t1-6分區(qū) C0-1將消費t1-3、t1-1、t1-9分區(qū) C1-0將消費t1-0、t1-4分區(qū) C1-1將消費t1-8、t1-7分區(qū)多個主題的分區(qū)分配和單個主題類似,這里就不在介紹了。
上面RoundRobin要求每個consumer訂閱的topic必須相同,當(dāng)訂閱的topic不同時,那么在執(zhí)行分區(qū)分配的時候就不是完全的輪詢分配,有可能會導(dǎo)致分區(qū)分配的不均勻。比如,某個consumer沒有訂閱消費組內(nèi)的某個topic,那么在分配分區(qū)的時候,這個consumer將分配不到這個topic的分區(qū)。
除了上述的介紹的RoundRobin和Range分配策略,Kafka還有Sticky分配策略,它主要有兩個目的:
當(dāng)兩者發(fā)生沖突時,第一個目標(biāo)優(yōu)先于第二個目標(biāo)。鑒于這兩個目標(biāo),StickyAssignor策略的具體實現(xiàn)要比RangeAssignor和RoundRobinAssignor這兩種分配策略要復(fù)雜很多。
關(guān)注 微信公眾號:大數(shù)據(jù)學(xué)習(xí)與分享,獲取更多技術(shù)干貨
推薦文章:
Kafka作為消息系統(tǒng)的系統(tǒng)補充?mp.weixin.qq.com分布式流平臺Kafka?mp.weixin.qq.comSparkStreaming和Kafka基于Direct Approach如何管理offset?mp.weixin.qq.com總結(jié)
以上是生活随笔為你收集整理的kafka consumer配置拉取速度慢_Kafka分区分配策略(Partition Assignment Strategy)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络中的计算机如果加入家庭组,win10
- 下一篇: 站酷用HTML5播放视频,站酷:动效展示