孟月昊 林榮霞 馮文 劉全兵
摘? 要: 在實際應用Kafka系統(tǒng)過程中,常因分區(qū)策略選擇不當而導致系統(tǒng)負載不均衡,節(jié)點經(jīng)常下線,影響業(yè)務工作。文章從消費速率變化和CPU使用率兩個方面切入,研究分析了RangeAssignor、RoundRobinAssignor、StickyAssignor三種分區(qū)策略對Kafka在系統(tǒng)開銷和負載均衡方面的影響,得出了這三種分區(qū)策略對系統(tǒng)影響的特點,對在實際生產(chǎn)應用Kafka過程中分區(qū)策略的選擇和使用,起到了一定的參考作用。
關(guān)鍵詞: 分布式消息系統(tǒng); Kafka; 分區(qū)策略; 系統(tǒng)開銷
中圖分類號:TP301.6? ? ? ? ? 文獻標識碼:A? ? ?文章編號:1006-8228(2020)11-11-05
Abstract: In the actual application of the Kafka, the system load is often unbalanced due to improper partitioning strategy selection, which results the nodes go offline and affects business work. In order to solve the problem, this paper focus on the changes of consumption rate and CPU utilization rate, studied and analyzed the influence of RangeAssignor, RoundRobinAssignor and StickyAssignor on system overhead and system stability when Kafka applied, and summarized the characteristics of the three partition strategies. This paper offers a reference for the selection and usage of partition strategy in the actual application of Kafka.
Key words: distributed messaging system; Kafka; partitioning strategy; system overhead
0 引言
隨著大數(shù)據(jù)技術(shù)的廣泛使用,分布式消息系統(tǒng)的應用也越來越廣泛。目前分布式消息系統(tǒng)大多采用消息中間件的分布式架構(gòu),而處理消息一般采用發(fā)布訂閱模式[1-3]。目前比較典型的分布式消息系統(tǒng)主要包括Microsoft MSMQ、RabbitMQ[4]以及Kafka等。其中Kafka相比其他分布式消息系統(tǒng),在消息派發(fā)方面有著獨特的優(yōu)勢,它以高吞吐量、水平擴展、可靠性高等特性而被廣泛使用,能夠收集和提交海量日志數(shù)據(jù),并處理實時和離線數(shù)據(jù)[5-7]。
Kafka集群主要包含生產(chǎn)者(producer),消費者(consumer),消息中間件處理節(jié)點(broker)以及一個zookeeper集群[8]。Kafka按照建立的主題(topic)對收集的消息進行分類放置,并在topic內(nèi)部劃分分區(qū)(partition),并將partition中的消息分配給consumer消費。此外,Kafka通過zookeeper集群,對producer、consumer以及broker進行注冊,在partition中選舉leader消息副本對外提供主要服務,且在consumer數(shù)量發(fā)生改變時進行負載均衡;producer使用push模式將消息發(fā)布到broker;consumer使用pull模式從broker中訂閱消費消息[9-10],如圖1所示。
其中Kafka負載均衡[11]是一個重要的核心功能,它根據(jù)消費者數(shù)量的變化來對partition進行重分配,目前Kafka主要有三種分區(qū)策略[12]:RangeAssignor、RoundRobinAssignor、StickyAssignor。在實際應用過程中,常因分區(qū)策略選擇不當,導致Kafka系統(tǒng)負載不均衡,性能不夠穩(wěn)定,節(jié)點下線,影響了業(yè)務工作與經(jīng)濟生產(chǎn)。另一方面,有關(guān)這三種分區(qū)策略的資料文獻大部分是對算法思想和流程的分析。對于Kafka實際應用中如何選擇分區(qū)策略以及不同分區(qū)策略對系統(tǒng)性能的影響研究分析的卻很少,無法為分區(qū)策略的選擇提供參考。
針對三種分區(qū)策略選擇和使用的問題,本文從分區(qū)策略對系統(tǒng)性能影響的方面切入,通過實驗數(shù)據(jù)研究分析對比了consumer消費速率變化以及CPU使用率兩個方面,并得出三種分區(qū)策略對系統(tǒng)性能影響的特點,為Kafka實際應用中如何選擇分區(qū)策略提供了一定的參考。
1 分區(qū)策略算法概述
1.1 RangeAssignor分區(qū)策略
RangeAssignor策略的原理是按照consumer總數(shù)和partition總數(shù)進行整除運算來獲得一個跨度n,然后將partition按照跨度進行平均分配,以保證partition盡可能均勻地分配給所有的consumer。對于每一個topic,RangeAssignor策略會將消費組內(nèi)所有訂閱這個topic的consumer按照名稱的字典序排序,然后為每個consumer進行分區(qū)分配,如果不能平均分配,那么字典序靠前的consumer會被多分配一個分區(qū)。分配策略如下:
跨度[n=分區(qū)數(shù)消費者數(shù)量],余數(shù)m=分區(qū)數(shù)%消費者數(shù)量
前m個消費者每個分配n+1個分區(qū),后(消費者數(shù)量-m)個消費者每個分配n個分區(qū)。假設(shè)有一個topic,4個partition,在同一個消費組內(nèi)consumer數(shù)量不同的情況下,partition分配如圖2所示。
⑴ partition/consumer能被整除。n=4/2=2,m=0能夠整除,所以每個consumer能夠均分到2個partition,如圖2(a)所示。四個分區(qū)二個consumer的場景,分配結(jié)果如下:C0:[P0,P1],C1:[P2,P3]。
⑵ partition/consumer不能被整除,且新增consumer之后,consumer總數(shù)量小于partition數(shù)量n=4/3=1···1,m=1,所以第一個consumer分配1+1=2個partition,后面4-1=3個consumer每個分配一個分區(qū),如圖2(b)所示。
四個分區(qū)三個消費者的場景,分配結(jié)果如下:C0: [P0,P1],C1:[P2],C2:[P3]無法完全平衡分配的場景,排序更靠前的消費者分配到更多的分區(qū)。
當新增越多的topic,則分配不平衡越明顯。例如再新增一個partition為4的Topic,分配情況如圖3所示。
分配結(jié)果:訂閱2個Topic,每個Topic四個分區(qū),共3個Consumer。C0:[T0P0,T0P1,T1P0,T1P1],C1:[T0P2,T1P2],C2:[T0P3,T1P3],這種不平衡的情況會越來越嚴重。
⑶ 當consumer數(shù)量大于partition數(shù)量時,排序靠前的consumer能先分到partition,排序靠后的consumer可能分不到partition,且partition是均分給consumer,如圖2(c)所示。
四個分區(qū)五個消費者的場景,分配結(jié)果為:C0: [P0],C1:[P1],C2:[P2],C3:[P3],C4:[P4]消費者數(shù)量超過分區(qū)數(shù)量時,排序更靠前的消費者先分配到分區(qū),排序靠后的消費者可能分配不到分區(qū)。
1.2 RoundRobinAssignor分區(qū)策略
RoundRobinAssignor策略的原理是將所有consumer以及所訂閱的所有topic的partition按照字典序排序,然后通過輪詢方式逐個將partition依次分配給每個consumer。
⑴ 如果同一個消費組內(nèi)所有consumer訂閱的topic都是相同的,那么分配結(jié)果是盡量相同的,如圖4所示,分配結(jié)果:C0:[T0P0,T0P3],C1:[T0P1],C2:[T0P2]。無法完全平衡分配,排序靠前的consumer分配到更多的分區(qū)。
⑵ 如果同一個消費組內(nèi)所有的consumer訂閱的topic是不相同的,那么分配的分區(qū)不能保證盡可能的均勻。假設(shè)有三個消費者分別為C0、C1、C2,有3個Topic T0、T1、T2,分別擁有1、2、3個分區(qū),并且C0訂閱T0,C1訂閱T0和T1,C2訂閱T0、T1、T0,沒有訂閱對應topic的consumer不參與分配,則分配結(jié)果如下:C0:[T0P0],C1:[T1P0],C2:[T1P1,T2P0,T2P1,T2P2]。如圖5所示。
從分配結(jié)果可以看出,完全可以把T1P1交給C1進行消費,使得分區(qū)分配更加均衡。
1.3 StickyAssignor分區(qū)策略
針對RangeAssignor和RoundRobinAssignor分區(qū)分配不均衡的問題,從Kafka0.11x版本開始引入了StickyAssignor算法以優(yōu)化分區(qū)分配。算法的目標主要有兩點:一是分區(qū)的分配盡量均衡;二是每次重分配的結(jié)果盡量與上一次分配結(jié)果保持一致。當兩個目標發(fā)生沖突時,優(yōu)先保證第一個目標。第一個目標是每種分配算法都盡量嘗試去完成的,而第二個目標才真正體現(xiàn)出StickyAssignor特性,即每一次分配變更相對上一次分配做最少的變動。
⑴ 同一消費組內(nèi)所有consumer訂閱的topic相同
假設(shè)有4個topic:T0,T1,T2,T3,每個topic有2個partition。共有3個consumer:C0,C1,C2,所有consumer都訂閱了這四個分區(qū)。StickyAssignor具體分配過程如圖6所示。
StickyAssignor初始分配的結(jié)果與RoundRobin-Assignor相同,結(jié)果為C0:[T0P0,T1P1,T3P0],C1:[T0P1,T2P0,T3P1],C2:[T1P0,T2P1]。當C1下線之后,按照盡量少移動分區(qū)的原則,只對C1的分區(qū)T0P1,T2P0,T3P1進行分配,結(jié)果如下:C0:[T0P0,T1P1,T3P0,T2P0],C2:[T1P0,T2P1,T0P1,T3P1],最終達到C0,C1分區(qū)平衡。
⑵ 同一消費組內(nèi)所有consumer訂閱的topic不同
仍以RoundRobinAssignor所有consumer訂閱topic的例子為例并與其進行對比,如圖7所示。
RoundRobinAssignor分配結(jié)果為:C1:[T0P0,T1P1],C2:[T1P0,T2P0,T2P1,T3P1]。StickyAssignor分配結(jié)果為:C1:[T0P0,T1P0,T1P1],C2:[T2P0,T2P1,T2P2]。從分配過程可以看出,StickyAssignor的分配策略比RangeAssignor、RoundRobinAssignor更加均衡和優(yōu)化。
2 分區(qū)策略性能分析與對比
實驗環(huán)境所用的三臺主機配置為CPU Intel? Corei7-6700 3.4GHz,內(nèi)存8GB,操作系統(tǒng)Redhat7.2,Kafka相關(guān)組件版本為Apache-zookeeper-3.5.5,Kafka_2.11-2.2.0。
三臺主機分別為broker0,broker1,broker2。創(chuàng)建三個topic,記為t0,t1,t2,t0創(chuàng)建4個partition,t1創(chuàng)建4個partition,t2創(chuàng)建5個partition。在三臺主機上分別創(chuàng)建1個consumer,分別記為C0,C1,C2,且三個consumer均屬于同一個消費組。其中C0訂閱t0中的消息,C1訂閱t0,t1中的消息,C2訂閱t0,t1,t2中的消息。創(chuàng)建producer,并利用Kafka生產(chǎn)者相關(guān)命令隨機生成10000000條數(shù)據(jù),每條長度為1000字節(jié),存入本地磁盤。
2.1 對consumer消費速率變化影響的對比
修改Kafka配置文件中consumer.properties文件,將分區(qū)策略參數(shù)partition.assignment.strategy的值依次設(shè)為RangeAssignor、RoundRobinAssignor、StickyAssignor,其他所有參數(shù)和其他配置文件均保持相同。
啟動C0,C1,C2對消息進行消費。待消費速率穩(wěn)定后,在某一時刻將C0下線,每隔5s記錄一次C1,C2的消費速率,并計算出消費速率增量,記為?V1和?V2,則每種分區(qū)策略的消費速率增量記為?V=?V1+?V2。同理,在第25s時候?qū)0上線,記錄?V值。如表1所示,記錄了C0下線和上線兩種情況下,三種分區(qū)策略?V的值。圖8為根據(jù)表1記錄的數(shù)據(jù)生成的消費速率增量與時間圖。
如圖8所示,根據(jù)Kafka的consumer獲得的 partition越多,消費速率越大,反之越小的特性。當C0下線時,所有topic和partition會進行重分配。C0訂閱的partition會分配給C1和C2,所以C1和C2的消費速率都會增大,但是StickyAssignor策略比另外兩種策略速率增量較小,增量趨勢也相對平緩。而RangeAssignor和RoundRobinAssignor兩種策略速率增量較大,增量趨勢相對更加陡峭。當? C0上線時,同樣會進行topic和partition的重分配,C1和C2的分區(qū)會有所減少,所以C1和C2的消費速率會下降,但速率增量的變化情況和C0下線時一樣,StickyAssignor策略比另外兩種策略要平緩。因此,從總體可以看出,StickyAssignor分區(qū)策略要比RangeAssignor和RoundRobinAssignor兩種策略在應對partition變動以及重分配的情況時,對con-sumer消費消息影響較小,不會有劇烈的變化。這點對于在實際高吞吐高并發(fā)情況下Kafka系統(tǒng)出現(xiàn)topic和partition變化時,consumer性能的穩(wěn)定性上有一定的幫助,有助于提高Kafka系統(tǒng)的穩(wěn)定性。
2.2 對CPU使用率影響的對比
在系統(tǒng)穩(wěn)定運行的某一時刻起,每隔5s記錄一次C1和C2的CPU使用率,并以C1與C2的CPU使用率之和作為分區(qū)策略的CPU使用率。從記錄數(shù)據(jù)開始的第20s時刻,將C0下線,在第40s時刻將C0上線。表2為60s時間段內(nèi)三種分區(qū)策略的CPU使用率,圖9為CPU使用率與時間分布圖。
由表2和圖9可知,C0的下線和上線RangeAssignor和RoundRobinAssignor兩種策略都會進行重分區(qū)和負載均衡,這兩種分區(qū)策略的CPU使用率迅速上升到一個峰值,說明系統(tǒng)開銷較大,在實際應用過程中,系統(tǒng)容易出現(xiàn)負載不均衡的情況,很可能使某個consumer節(jié)點成為“熱點”,出現(xiàn)節(jié)點宕機的情況。而StickyAssignor策略CPU使用率上升緩慢,開銷變化比另兩種分區(qū)策略較小,更晚的出現(xiàn)峰值。說明StickyAssignor策略在進行重分區(qū)和負載均衡時對系統(tǒng)的影響較小,較另外兩種分區(qū)策略在負載均衡方面更有效,應用中出現(xiàn)“熱點”節(jié)點的概率較低,增強了系統(tǒng)的健壯性。但StickyAssignor策略整體算法復雜度較另兩種策略偏高,因此整體的CPU使用率偏高。
由以上實驗可知,當Kafka系統(tǒng)對穩(wěn)定要求較高時,StickyAssignor策略是個較為合適的選擇。而對穩(wěn)定性要求不高且考慮到系統(tǒng)開銷時,選擇Range-
Assignor和RoundRobinAssignor兩種策略較為合適。其中RoundRobinAssignor策略較RangeAssignor策略在分區(qū)分配方面更為均衡,出現(xiàn)“熱點”節(jié)點和負載不均衡的問題概率較低。
3 結(jié)束語
本文從consumer消費速率變化和CPU使用率兩個方面對Kafka的三種分區(qū)策略作了對比分析。實驗結(jié)果表明,在Kafka系統(tǒng)進行負載均衡過程中,StickyAssignor策略較另外兩種策略有更好的穩(wěn)定性,消費速率變化和CPU使用率沒有過大的波動,降低了Kafka系統(tǒng)出現(xiàn)負載不均,和“過熱”節(jié)點出現(xiàn)的概率,增強了系統(tǒng)的健壯性。RangeAssignor、RoundRobin-
Assignor兩種策略相對StickyAssignor算法復雜度較低,因此在CPU使用率和系統(tǒng)開銷方面較小。但在partition重分配過程中系統(tǒng)性能波動較大,容易造成負載不均衡的問題,降低系統(tǒng)穩(wěn)定性。通過實驗得出了三種策略對Kafka系統(tǒng)性能影響的特點,并提出了一些策略選擇的建議。對于在實際生產(chǎn)應用Kafka系統(tǒng)進行分區(qū)策略選擇時,能夠起到一定的參考作用,特別是在高復雜性,高穩(wěn)定性,高吞吐量應用場景下更具參考價值。
參考文獻(References):
[1] 邸宇飛.基于Kafka的高速流量存儲分發(fā)系統(tǒng)的研究與應用[D].北京郵電大學,2016.
[2] A distributed publish/subscribe notification service for pervasive environments[Ph.D.Thesis]. Zeidler,2004.
[3] 朱幼普.基于Kafka分布式能效管理平臺的研究與應用[D].武漢郵電科學研究院,2018.
[4] Rabbit MQ in action. Videla A,Williams J J W,2012.
[5] Streaming Big Data Processing in Datacenter Clouds.Ranjan Rajiv. IEEE Cloud Computing,2014.
[6] 馬建剛,黃濤,汪錦嶺,徐罡,葉丹.面向大規(guī)模分布式計算發(fā)布訂閱系統(tǒng)核心技術(shù)[J].軟件學報,2006.1:134-147
[7] 馬振剛.基于Kafka和Hadoop架構(gòu)的工程研發(fā)數(shù)據(jù)挖掘[J].上海汽車,2020.6:12-16
[8] 倪超.從Paxos到Zookeeper分布式一致性原理[M].電子工業(yè)出版社,2015.
[9] 許紅軍.使用安全機制管理Kafka消息隊列[J].網(wǎng)絡(luò)安全和信息化,2020.5:134-139
[10] 王巖,王純.一種基于Kafka的可靠的Consumer的設(shè)計方案[J].軟件,2016.37(1):61-66
[11] 王鄭合,王鋒,鄧輝,柳翠寅,張曉麗.一種優(yōu)化的Kafka消費者/客戶端負載均衡算法[J].計算機應用研究,2017.34(8):2306-2309
[12] 朱忠華.深入理解Kafka[M].電子工業(yè)出版社,2019.