怎么實(shí)現(xiàn)kafka性能技術(shù)分析

本篇文章為大家展示了怎么實(shí)現(xiàn)kafka性能技術(shù)分析,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

創(chuàng)新互聯(lián)公司專注于網(wǎng)站建設(shè),為客戶提供網(wǎng)站設(shè)計(jì)制作、網(wǎng)站設(shè)計(jì)、網(wǎng)頁(yè)設(shè)計(jì)開發(fā)服務(wù),多年建網(wǎng)站服務(wù)經(jīng)驗(yàn),各類網(wǎng)站都可以開發(fā),品牌網(wǎng)站建設(shè),公司官網(wǎng),公司展示網(wǎng)站,網(wǎng)站設(shè)計(jì),建網(wǎng)站費(fèi)用,建網(wǎng)站多少錢,價(jià)格優(yōu)惠,收費(fèi)合理。

1.通過磁盤順序讀寫,效率高,appendLog,對(duì)比raid-5 7200rpm的磁盤

sequence io 600M/s

random io 100kb/s

kafka寫操作時(shí),依賴底層文件系統(tǒng)的pagecache功能,pagecache會(huì)將盡量多的將空閑內(nèi)存,當(dāng)做磁盤緩存,寫操作先寫到pageCache,并將該page標(biāo)記為dirty;發(fā)生讀操作時(shí),會(huì)先從pageCache中查找,當(dāng)發(fā)生缺頁(yè)時(shí),才會(huì)去磁盤調(diào)整;當(dāng)有其他應(yīng)用申請(qǐng)內(nèi)存時(shí),回收pageCache的代價(jià)是很低的

,使用pageCache的緩存功能,會(huì)減少我們隊(duì)JVM的內(nèi)存依賴,JVM為我們提供了GC功能,依賴JVM內(nèi)存在kafka高吞吐,大數(shù)據(jù)的場(chǎng)景下有很多問題。如果heap管理緩存,那么JVM的gc會(huì)頻繁掃描heap空間,帶來的開銷很大,如果heap過大,full gc帶來的成本也很高;所有的In-Process Cache在OS中都有一份同樣的PageCache。所以通過只在PageCache中做緩存至少可以提高一倍的緩存空間。如果Kafka重啟,所有的In-Process  Cache都會(huì)失效,而OS管理的PageCache依然可以繼續(xù)使用。

2.sendFile

傳統(tǒng)網(wǎng)絡(luò)IO模型

① 操作系統(tǒng)將數(shù)據(jù)從磁盤拷貝到內(nèi)核區(qū)的pagecache

② 用戶程序?qū)?nèi)核區(qū)的pagecache拷貝到用戶區(qū)緩存

③ 用戶程序?qū)⒂脩魠^(qū)的緩存拷貝到socket緩存中

④ 操作系統(tǒng)將socket緩存中的數(shù)據(jù)拷貝到網(wǎng)卡的buffer上,發(fā)送

怎么實(shí)現(xiàn)kafka性能技術(shù)分析

問題:四次system call 兩次context切換,同一份數(shù)據(jù)在緩存中拷貝多次,效率很低,拷貝動(dòng)作完全可以在內(nèi)核中進(jìn)行,將2 3 步去掉,sendfile就是完成這一功能

怎么實(shí)現(xiàn)kafka性能技術(shù)分析

kafka設(shè)計(jì)初衷是數(shù)據(jù)的拷貝完全通過pageCache來進(jìn)行,盡量減少磁盤讀寫,如果kafka生產(chǎn)消費(fèi)配合的好,那么數(shù)據(jù)完全走內(nèi)存,這對(duì)集群的吞吐量提升是很大的

當(dāng)集群只有寫操作時(shí),此時(shí)的集群只有寫,沒有讀操作。10M/s左右的Send的流量是Partition之間進(jìn)行Replicate而產(chǎn)生的。從recv和writ的速率比較可以看出,寫盤是使用Asynchronous+Batch的方式,底層OS可能還會(huì)進(jìn)行磁盤寫順序優(yōu)化。而在有Read Request進(jìn)來的時(shí)候分為兩種情況,第一種是內(nèi)存中完成數(shù)據(jù)交換。

怎么實(shí)現(xiàn)kafka性能技術(shù)分析

② 已經(jīng)從pageCache刷出的數(shù)據(jù),這時(shí)候的數(shù)據(jù)可以看出大部分走的是磁盤io

怎么實(shí)現(xiàn)kafka性能技術(shù)分析
怎么實(shí)現(xiàn)kafka性能技術(shù)分析

TIPS

① kafka官方不建議使用log.flush.interval.messages和log.flush.interval.ms來強(qiáng)制刷盤,因?yàn)楦呖煽繎?yīng)該通過replica副本來保證,強(qiáng)制刷盤對(duì)系統(tǒng)性能影響很大(生產(chǎn)是100000 和60000)

② 可以通過調(diào)整/proc/sys/vm/dirty_background_ratio和/proc/sys/vm/dirty_ratio來調(diào)優(yōu)性能。

a. 臟頁(yè)率超過第一個(gè)指標(biāo)會(huì)啟動(dòng)pdflush開始Flush Dirty PageCache。

b. 臟頁(yè)率超過第二個(gè)指標(biāo)會(huì)阻塞所有的寫操作來進(jìn)行Flush。

c. 根據(jù)不同的業(yè)務(wù)需求可以適當(dāng)?shù)慕档蚫irty_background_ratio和提高dirty_ratio。

(生產(chǎn)是10 和 20)

2 partition

Partition是Kafka可以很好的橫向擴(kuò)展和提供高并發(fā)處理以及實(shí)現(xiàn)Replication的基礎(chǔ)。

擴(kuò)展性方面。首先,Kafka允許Partition在集群內(nèi)的Broker之間任意移動(dòng),以此來均衡可能存在的數(shù)據(jù)傾斜問題。其次,Partition支持自定義的分區(qū)算法,例如可以將同一個(gè)Key的所有消息都路由到同一個(gè)Partition上去。 同時(shí)Leader也可以在In-Sync的Replica中遷移。由于針對(duì)某一個(gè)Partition的所有讀寫請(qǐng)求都是只由Leader來處理,所以Kafka會(huì)盡量把Leader均勻的分散到集群的各個(gè)節(jié)點(diǎn)上,以免造成網(wǎng)絡(luò)流量過于集中。

并發(fā)方面。任意Partition在某一個(gè)時(shí)刻只能被一個(gè)Consumer Group內(nèi)的一個(gè)Consumer消費(fèi)(反過來一個(gè)Consumer則可以同時(shí)消費(fèi)多個(gè)Partition),Kafka非常簡(jiǎn)潔的Offset機(jī)制最小化了Broker和Consumer之間的交互,這使Kafka并不會(huì)像同類其他消息隊(duì)列一樣,隨著下游Consumer數(shù)目的增加而成比例的降低性能。此外,如果多個(gè)Consumer恰巧都是消費(fèi)時(shí)間序上很相近的數(shù)據(jù),可以達(dá)到很高的PageCache命中率,因而Kafka可以非常高效的支持高并發(fā)讀操作,實(shí)踐中基本可以達(dá)到單機(jī)網(wǎng)卡上限。

不過,Partition的數(shù)量并不是越多越好,Partition的數(shù)量越多,平均到每一個(gè)Broker上的數(shù)量也就越多??紤]到Broker宕機(jī)(Network Failure, Full GC)的情況下,需要由Controller來為所有宕機(jī)的Broker上的所有Partition重新選舉Leader,假設(shè)每個(gè)Partition的選舉消耗10ms,如果Broker上有500個(gè)Partition,那么在進(jìn)行選舉的5s的時(shí)間里,對(duì)上述Partition的讀寫操作都會(huì)觸發(fā)LeaderNotAvailableException。

再進(jìn)一步,如果掛掉的Broker是整個(gè)集群的Controller,那么首先要進(jìn)行的是重新任命一個(gè)Broker作為Controller。新任命的Controller要從Zookeeper上獲取所有Partition的Meta信息,獲取每個(gè)信息大概3-5ms,那么如果有10000個(gè)Partition這個(gè)時(shí)間就會(huì)達(dá)到30s-50s。而且不要忘記這只是重新啟動(dòng)一個(gè)Controller花費(fèi)的時(shí)間,在這基礎(chǔ)上還要再加上前面說的選舉Leader的時(shí)間 -_-!!!!!!

此外,在Broker端,對(duì)Producer和Consumer都使用了Buffer機(jī)制。其中Buffer的大小是統(tǒng)一配置的,數(shù)量則與Partition個(gè)數(shù)相同。如果Partition個(gè)數(shù)過多,會(huì)導(dǎo)致Producer和Consumer的Buffer內(nèi)存占用過大。

tips

1. Partition的數(shù)量盡量提前預(yù)分配,雖然可以在后期動(dòng)態(tài)增加Partition,但是會(huì)冒著可能破壞Message Key和Partition之間對(duì)應(yīng)關(guān)系的風(fēng)險(xiǎn)。

2. Replica的數(shù)量不要過多,如果條件允許盡量把Replica集合內(nèi)的Partition分別調(diào)整到不同的Rack。

3. 盡一切努力保證每次停Broker時(shí)都可以Clean Shutdown,否則問題就不僅僅是恢復(fù)服務(wù)所需時(shí)間長(zhǎng),還可能出現(xiàn)數(shù)據(jù)損壞或其他很詭異的問題。

3

Producer

Kafka的研發(fā)團(tuán)隊(duì)表示在0.8版本里用Java重寫了整個(gè)Producer,據(jù)說性能有了很大提升。我還沒有親自對(duì)比試用過,這里就不做數(shù)據(jù)對(duì)比了。本文結(jié)尾的擴(kuò)展閱讀里提到了一套我認(rèn)為比較好的對(duì)照組,有興趣的同學(xué)可以嘗試一下。

其實(shí)在Producer端的優(yōu)化大部分消息系統(tǒng)采取的方式都比較單一,無非也就化零為整、同步變異步這么幾種。

Kafka系統(tǒng)默認(rèn)支持MessageSet,把多條Message自動(dòng)地打成一個(gè)Group后發(fā)送出去,均攤后拉低了每次通信的RTT。而且在組織MessageSet的同時(shí),還可以把數(shù)據(jù)重新排序,從爆發(fā)流式的隨機(jī)寫入優(yōu)化成較為平穩(wěn)的線性寫入。

此外,還要著重介紹的一點(diǎn)是,Producer支持End-to-End的壓縮。數(shù)據(jù)在本地壓縮后放到網(wǎng)絡(luò)上傳輸,在Broker一般不解壓(除非指定要Deep-Iteration),直至消息被Consume之后在客戶端解壓。

當(dāng)然用戶也可以選擇自己在應(yīng)用層上做壓縮和解壓的工作(畢竟Kafka目前支持的壓縮算法有限,只有GZIP和Snappy),不過這樣做反而會(huì)意外的降低效率!?。?! Kafka的End-to-End壓縮與MessageSet配合在一起工作效果最佳,上面的做法直接割裂了兩者間聯(lián)系。至于道理其實(shí)很簡(jiǎn)單,壓縮算法中一條基本的原理“重復(fù)的數(shù)據(jù)量越多,壓縮比越高”。無關(guān)于消息體的內(nèi)容,無關(guān)于消息體的數(shù)量,大多數(shù)情況下輸入數(shù)據(jù)量大一些會(huì)取得更好的壓縮比。

不過Kafka采用MessageSet也導(dǎo)致在可用性上一定程度的妥協(xié)。每次發(fā)送數(shù)據(jù)時(shí),Producer都是send()之后就認(rèn)為已經(jīng)發(fā)送出去了,但其實(shí)大多數(shù)情況下消息還在內(nèi)存的MessageSet當(dāng)中,尚未發(fā)送到網(wǎng)絡(luò),這時(shí)候如果Producer掛掉,那就會(huì)出現(xiàn)丟數(shù)據(jù)的情況。

為了解決這個(gè)問題,Kafka在0.8版本的設(shè)計(jì)借鑒了網(wǎng)絡(luò)當(dāng)中的ack機(jī)制。如果對(duì)性能要求較高,又能在一定程度上允許Message的丟失,那就可以設(shè)置request.required.acks=0 來關(guān)閉ack,以全速發(fā)送。如果需要對(duì)發(fā)送的消息進(jìn)行確認(rèn),就需要設(shè)置request.required.acks為1或-1,那么1和-1又有什么區(qū)別呢?這里又要提到前面聊的有關(guān)Replica數(shù)量問題。如果配置為1,表示消息只需要被Leader接收并確認(rèn)即可,其他的Replica可以進(jìn)行異步拉取無需立即進(jìn)行確認(rèn),在保證可靠性的同時(shí)又不會(huì)把效率拉得很低。如果設(shè)置為-1,表示消息要Commit到該P(yáng)artition的ISR集合中的所有Replica后,才可以返回ack,消息的發(fā)送會(huì)更安全,而整個(gè)過程的延遲會(huì)隨著Replica的數(shù)量正比增長(zhǎng),這里就需要根據(jù)不同的需求做相應(yīng)的優(yōu)化。

tips

1. Producer的線程不要配置過多,尤其是在Mirror或者M(jìn)igration中使用的時(shí)候,會(huì)加劇目標(biāo)集群Partition消息亂序的情況(如果你的應(yīng)用場(chǎng)景對(duì)消息順序很敏感的話)。

2. 0.8版本的request.required.acks默認(rèn)是0(同0.7)。

4

Consumer

Consumer端的設(shè)計(jì)大體上還算是比較常規(guī)的。

? 通過Consumer Group,可以支持生產(chǎn)者消費(fèi)者和隊(duì)列訪問兩種模式。

? Consumer API分為High level和Low level兩種。前一種重度依賴Zookeeper,所以性能差一些且不自由,但是超省心。第二種不依賴Zookeeper服務(wù),無論從自由度和性能上都有更好的表現(xiàn),但是所有的異常(Leader遷移、Offset越界、Broker宕機(jī)等)和Offset的維護(hù)都需要自行處理。

? 大家可以關(guān)注下不日發(fā)布的0.9 Release。這幫貨又用Java重寫了一套Consumer。把兩套API合并在一起,同時(shí)去掉了對(duì)Zookeeper的依賴。據(jù)說性能有大幅度提升哦~~

tips

強(qiáng)烈推薦使用Low level API,雖然繁瑣一些,但是目前只有這個(gè)API可以對(duì)Error數(shù)據(jù)進(jìn)行自定義處理,尤其是處理Broker異?;蛴捎赨nclean Shutdown導(dǎo)致的Corrupted Data時(shí),否則無法Skip只能等著“壞消息”在Broker上被Rotate掉,在此期間該Replica將會(huì)一直處于不可用狀態(tài)。

上述內(nèi)容就是怎么實(shí)現(xiàn)kafka性能技術(shù)分析,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

網(wǎng)頁(yè)標(biāo)題:怎么實(shí)現(xiàn)kafka性能技術(shù)分析
分享鏈接:http://muchs.cn/article16/pdghgg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、網(wǎng)站維護(hù)Google、品牌網(wǎng)站制作建站公司、服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)