一文理解kafka?rebalance負(fù)載均衡
介紹
今天主要分享一下 kafka 的 rebalance,在 kafka 中,rebalance 是一個(gè)十分重要的概念,很多時(shí)候引發(fā)的一些問題可能都是由于 rebalance 引起的,rebalance 也就是再均衡,顧名思義,再均衡就是再次負(fù)載均衡,下面會(huì)對再均衡進(jìn)行一個(gè)詳細(xì)的描述。
負(fù)載均衡
說再均衡之前,先說一說負(fù)載均衡,負(fù)載均衡就是將請求分發(fā)到不同的操作單元上,我們通俗一點(diǎn)來說,就是將請求分發(fā)到不同的服務(wù)器上,以減輕單臺(tái)服務(wù)器的壓力,提高吞吐量,負(fù)載均衡的方式有很多,下面是 nginx 的負(fù)載均衡,當(dāng)客戶端請求到 nginx 時(shí),nginx 根據(jù)一定的負(fù)載均衡算法將請求轉(zhuǎn)發(fā)到不同的服務(wù)器。
請求應(yīng)該落到那一臺(tái)機(jī)器上,這取決于我們使用的負(fù)載均衡策略,負(fù)載均衡策略有很多,比如隨機(jī),輪詢,LFU,LRU 等等,這取決于我們的選擇。
rebalance圖示
上面說了負(fù)載均衡,其實(shí)再均衡也是一樣,再 kafka 中,一個(gè)消費(fèi)者群組怎么去消費(fèi)一個(gè)主題下面的分區(qū),該以什么方式去消費(fèi)這些分區(qū),是我們值得去考慮的,kafka 提供了一個(gè)分區(qū)分配器,他能協(xié)調(diào)哪些消費(fèi)者應(yīng)該去消費(fèi)那些分區(qū)。
如下圖所示,一個(gè)消費(fèi)者群組中有兩個(gè)消費(fèi)者,他們各自消費(fèi)兩個(gè)分區(qū)。
此時(shí)加入一個(gè)消費(fèi)者,那么就觸發(fā)了再均衡操作,kafka 就會(huì)重新進(jìn)行分配,分配后的樣子可能是下面的這樣,c2 從原來的消費(fèi)兩個(gè)分區(qū) partition-3,partition-4 變?yōu)橹幌M(fèi) partition-2,partition-4 讓 c3 去消費(fèi)。
從上面我們看出,kafka 的再均衡其實(shí)就是協(xié)調(diào)消費(fèi)者和分區(qū)的消費(fèi)對應(yīng)關(guān)系,我們一般是希望消費(fèi)者和分區(qū)之間的消費(fèi)關(guān)系盡量做到平衡,別出現(xiàn)某個(gè)消費(fèi)者的負(fù)載很高,某個(gè)消費(fèi)者的負(fù)載很低,資源不能進(jìn)行合理的利用。
再均衡產(chǎn)生的條件
再均衡產(chǎn)生的條件就是有消費(fèi)者加入或者退出,加入和退出的方式有很多,有一些是主動(dòng)因素,有一些是被動(dòng)因素,比如我們主動(dòng)增加一個(gè)消費(fèi)者,這時(shí)候就會(huì)發(fā)生再均衡,我們停掉一個(gè)消費(fèi)者,那么這時(shí)候也發(fā)生再均衡,還有當(dāng)消費(fèi)者和 broker 之間由于長時(shí)間沒有心跳,那么消費(fèi)者就被提出,這時(shí)候也會(huì)發(fā)生再均衡,某個(gè)主題下的分區(qū)數(shù)量發(fā)生變化,也會(huì)發(fā)生再均衡,還有其他的一些因素,就不展開了,不過我們應(yīng)該盡量避免再均衡。
再均衡期間消費(fèi)者是讀取不了任何消息,因?yàn)檫@段時(shí)間會(huì)對分區(qū)進(jìn)行重新分配,所以 之前消費(fèi)者與分區(qū)之間的對應(yīng)關(guān)系已經(jīng)不存在,需要進(jìn)行重新分配,所以會(huì)出現(xiàn)短暫不可用現(xiàn)象。
主動(dòng)因素導(dǎo)致消費(fèi)者的加入和離開是無法避免的,當(dāng)數(shù)據(jù)量比較大時(shí),可能需要增加消費(fèi)者來分擔(dān)壓力,提高吞吐量,所以這時(shí)候就需要人為去添加消費(fèi)者了,這時(shí)候發(fā)生再均衡是可預(yù)見的,但是被動(dòng)導(dǎo)致再均衡就不可預(yù)見了,下面我們從一些參數(shù)和原理來說明一下,盡量避免再均衡。
相關(guān)參數(shù)
在 kafka 中,分區(qū)的分配和分區(qū)分配器PartitionAssignor有關(guān),在底層實(shí)現(xiàn)中,是通過協(xié)調(diào)器Coordinator來協(xié)調(diào)消費(fèi)者和分區(qū)的,分為消費(fèi)者端的消費(fèi)者協(xié)調(diào)器ConsumerCoordinator和 Broker 端的組協(xié)調(diào)器GroupCoordinator。
Broker 端參數(shù)
- group.max.session.timeout.ms:消費(fèi)者會(huì)話的最大超時(shí)時(shí)間。如果消費(fèi)者在這個(gè)時(shí)間內(nèi)沒有發(fā)送心跳 GroupCoordinator,那么它會(huì)被認(rèn)為已經(jīng)失效,會(huì)被踢出消費(fèi)組。
- group.min.session.timeout.ms:消費(fèi)者會(huì)話的最小超時(shí)時(shí)間。如果消費(fèi)者在這個(gè)時(shí)間內(nèi)沒有發(fā)送心跳 GroupCoordinator,那么它會(huì)被認(rèn)為已經(jīng)失效,會(huì)被踢出消費(fèi)組。
- group.initial.rebalance.delay.ms:消費(fèi)者組啟動(dòng)時(shí),等待多長時(shí)間再進(jìn)行 rebalance。這個(gè)參數(shù)可以讓消費(fèi)者有時(shí)間加入消費(fèi)者組。
consumer 端參數(shù)
- session.timeout.ms:消費(fèi)者會(huì)話的超時(shí)時(shí)間。如果一個(gè)消費(fèi)者在這個(gè)時(shí)間內(nèi)沒有發(fā)送心跳到組協(xié)調(diào)器 GroupCoordinator,那么被認(rèn)為它已經(jīng)失效了,就會(huì)將其踢出消費(fèi)者組。如果這個(gè)值設(shè)置過小,那么就會(huì)比較消耗資源,但是能夠快速的發(fā)現(xiàn) ConsumerCoordinator 是否還“存活”,然后進(jìn)行 rebalance,如果設(shè)置過大,那么就會(huì)導(dǎo)致長時(shí)間沒有收到心跳,可能 ConsumerCoordinator 已經(jīng)“掛了”一段時(shí)間,沒有及時(shí)進(jìn)行 rebalance。
- heartbeat.interval.ms:消費(fèi)者發(fā)送心跳的時(shí)間間隔。心跳是消費(fèi)者與 GroupCoordinator 之間維持會(huì)話的機(jī)制,如果一個(gè)消費(fèi)者在這個(gè)時(shí)間間隔內(nèi)沒有發(fā)送心跳,那么 GroupCoordinator 認(rèn)為它已經(jīng)失效,然后將其踢出,如果這個(gè)值設(shè)置過大,那么一個(gè)消費(fèi)者失效時(shí),可能需要等待很長時(shí)間才能觸發(fā) rebalance,如果過小那么就會(huì)比較消耗資源。
- max.poll.interval.ms:消費(fèi)者處理消息的最大時(shí)間間隔。如果消費(fèi)者在這個(gè)時(shí)間內(nèi)沒有消費(fèi)完消息導(dǎo)致不能 poll 消息,那么它將被認(rèn)為已經(jīng)失效,將被踢出消費(fèi)者組,這個(gè)值默認(rèn)為 5 分鐘。
heartbeat.interval.ms 的值一定要比 session.timeout.ms 小,官網(wǎng)建議是 1/3,比如 heartbeat.interval.ms 為 5s,那么 session.timeout.ms 為 15s,這樣的話在這個(gè)時(shí)間會(huì)話內(nèi)能收到三次心跳,不過這兩個(gè)的值也要在 Broker 端 group.max.session.timeout.ms(5min)和 group.min.session.timeout.ms(6s)的區(qū)間之間。
分配器
消費(fèi)者和分區(qū)之間進(jìn)行分配是由分配器來完成的,當(dāng)消費(fèi)者加入和離開時(shí)觸發(fā) reabalance,然后會(huì)使用分配器從新對分區(qū)和消費(fèi)者進(jìn)行分配,kafka 有一個(gè)分配器接口ConsumerPartitionAssignor,它的下面有一個(gè)抽象類AbstractPartitionAssignor,如果我們需要自定義分配器,那么集成抽象類AbstractPartitionAssignor即可,kafka 默認(rèn)提供了好幾種分配器,如 RoundRobinAssignor,RangeAssignor,StickyAssignor,CooperativeStickyAssignor,kafka 默認(rèn)使用 RangeAssignor。
如下,我創(chuàng)建了一個(gè)名稱為 musk 的主題,分區(qū)數(shù)為 4,然后創(chuàng)建一個(gè)消費(fèi)者,那么這時(shí)因?yàn)橹挥幸粋€(gè)消費(fèi)者,所以四個(gè)分區(qū)都劃給了它。
此時(shí)我又加入一個(gè)消費(fèi)者,因?yàn)榧尤胂M(fèi)者后會(huì)觸發(fā) rebalance,所以這時(shí)候就會(huì)對分區(qū)重新進(jìn)行分配,分配后如下,每個(gè)消費(fèi)者劃分了兩個(gè)分區(qū)。
對于分配器,kafka 自帶的已經(jīng)能夠滿足我們大多時(shí)候的需求,因?yàn)槲覀冊谑褂枚鄠€(gè)消費(fèi)者的時(shí)候,其實(shí)就是為了讓分區(qū)被均分給消費(fèi)組內(nèi)的消費(fèi)者,以達(dá)到壓力的分擔(dān)。
總結(jié)
從上面我們對 rebalance 進(jìn)行一些介紹,對 rebalance 產(chǎn)生的原因進(jìn)行說明,對消費(fèi)者協(xié)調(diào)器和組協(xié)調(diào)器進(jìn)行了解,對一些參數(shù)進(jìn)行詳解,還有通過測試 rebalance 來更加直觀說明 rebalance,rebalance 的觸發(fā)有很多方式,不過我們應(yīng)該盡量去避免它的發(fā)生,對于分區(qū)的修改,應(yīng)該盡量在一開始規(guī)劃好,不要后續(xù)去修改分區(qū),對于其他引起 rebalance 的因素,也應(yīng)該將其概率降到最低。
今天的分享就到這里,感謝你的觀看,我們下期見,如果文中有說得不合理或者不正確的地方,希望你能進(jìn)行指點(diǎn),更多關(guān)于kafka rebalance負(fù)載均衡的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot響應(yīng)處理實(shí)現(xiàn)流程詳解
這篇文章主要介紹了SpringBoot響應(yīng)處理實(shí)現(xiàn)流程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-10-10dockerfile-maven-plugin極簡教程(推薦)
這篇文章主要介紹了dockerfile-maven-plugin極簡教程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10詳解spring cloud構(gòu)建微服務(wù)架構(gòu)的網(wǎng)關(guān)(API GateWay)
這篇文章主要介紹了詳解spring cloud構(gòu)建微服務(wù)架構(gòu)的網(wǎng)關(guān)(API GateWay),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01JVM默認(rèn)時(shí)區(qū)為:Asia/Shanghai與java程序中GMT+08不一致異常
這篇文章主要介紹了JVM默認(rèn)時(shí)區(qū)為:Asia/Shanghai與java程序中GMT+08不一致異常問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10SpringBoot下使用自定義監(jiān)聽事件的流程分析
事件機(jī)制是Spring的一個(gè)功能,目前我們使用了SpringBoot框架,所以記錄下事件機(jī)制在SpringBoot框架下的使用,同時(shí)實(shí)現(xiàn)異步處理,這篇文章主要介紹了SpringBoot下使用自定義監(jiān)聽事件,需要的朋友可以參考下2023-08-08Spring Cloud重試機(jī)制與各組件的重試總結(jié)
這篇文章主要給大家介紹了關(guān)于Spring Cloud中重試機(jī)制與各組件的重試的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11