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