通过一个Kafka故障解决过程阐述架构师必须具备的架构思维
本文是Kafka系列第4篇,從問題出發(fā),從而探討集群分區(qū)遷移實(shí)戰(zhàn)、底層原理以及運(yùn)維時需要考慮的問題。
掌握一到兩門java主流中間件,是敲開BAT等大廠必備的技能,送給大家一個Java中間件學(xué)習(xí)路線,助力大家實(shí)現(xiàn)職場的蛻變。
Java進(jìn)階之梯,成長路線與學(xué)習(xí)資料,助力突破中間件領(lǐng)域
1、問題描述
某一天突然收到開發(fā)環(huán)境Kafka報 IO Exception(many open files),其相關(guān)的日志如下:
問題是發(fā)生在公司的開發(fā)環(huán)境,為了避免信息泄露,我在本地進(jìn)行了模擬,不影響本次問題的分析與學(xué)習(xí)。
2、問題分析
首先我們要能看懂Kafka-manager上的一些監(jiān)控指標(biāo),topic列表中關(guān)于topic的信息項(xiàng)如下所示:
-
topic
topic名稱 -
Partitions
分區(qū)數(shù) -
Brokers
該topic 隊(duì)列分布的broker數(shù)量。 -
Brokers Spread %
該topic中隊(duì)列在Broker中的使用率,例如集群中有5個broker,但topic只在4個broker上創(chuàng)建了隊(duì)列,那使用率為80%。 -
Brokers Skew %
topic的隊(duì)列傾斜率。如果集群中存在5個broker節(jié)點(diǎn),topic的總分區(qū)數(shù)量為4,副本因子為2,但這些隊(duì)列只分布在其中的4臺broker中。那topic的broker使用率(Broker Spread)為80%。眾所周知,引入多節(jié)點(diǎn)的目的就是負(fù)載均衡,隊(duì)列在broker中的分配自然是希望越均衡越好,期望每臺broker上存儲2個隊(duì)列(副本因子為2,總共8個隊(duì)列),表示沒有發(fā)生傾斜,如果一臺broker中的存在3個隊(duì)列,而另外一個broker上1個隊(duì)列,那說明發(fā)生了傾斜,計算公式為超過平均隊(duì)列數(shù)的broker節(jié)點(diǎn)個數(shù)除以總所在Broker數(shù)量,其Brokers Skew等于(1/3)=33%。
-
Brokers Leader Skew %
topic分區(qū)中Leader分區(qū)的傾斜率。在Kafka中,只有分區(qū)的Leader節(jié)點(diǎn)具有讀寫權(quán)限,真正影響性能讀寫性能的是Leader分區(qū)是否均衡,試想一下,如果一個topic有6個分區(qū),但所有的Leader分區(qū)只分布在一兩個Broker節(jié)點(diǎn)上,這個topic的寫入、讀取性能將受到制約,這個值建議維持在0%。 -
Replicas
副本數(shù)、副本因子,即一個分區(qū)數(shù)據(jù)存儲的份數(shù),該數(shù)值包含Leader分區(qū)。 -
Under Replicated %
沒有跟上復(fù)制進(jìn)度的副本比例,在Kafka的復(fù)制模型中,主分區(qū)負(fù)責(zé)讀寫,該復(fù)制組內(nèi)的其他副本從主節(jié)點(diǎn)同步數(shù)據(jù),如果跟不上主節(jié)點(diǎn)的復(fù)制進(jìn)度,將被提出ISR,被剔除ISR的副本不具備選舉Leader的資格,這個數(shù)據(jù)如果長期或頻繁高于0,說明集群一定出現(xiàn)了問題。 -
Producer Message/Sec
消息發(fā)送實(shí)時TPS,通過JMX采集,需要在kafka-manager中開啟如下參數(shù):
-
Summed Recent Offsets
該主題當(dāng)前最大的消息偏移量。
經(jīng)過對Topic列表觀察,發(fā)現(xiàn)開發(fā)環(huán)境存在大量的topic都只有一個隊(duì)列,并且都分布在第一節(jié)點(diǎn)上,其截圖如下:
從界面上對應(yīng)的指標(biāo):Brokers Spread即Broker的利用率只有3分之一,抽取幾個數(shù)據(jù)量大的主題,判斷其路由信息,得知都分布在第一個Broker節(jié)點(diǎn)上,這樣就導(dǎo)致其中一個節(jié)點(diǎn)大量出現(xiàn)文章開頭部分提到的錯誤:Too many open files。
3、解決方案
3.1 擴(kuò)分區(qū)
問題定位出來了,由于Broker利用率不均勻,大量topic只創(chuàng)建了一個隊(duì)列,并且還集中落到了第一個節(jié)點(diǎn)。
針對這種情況,首先想到的方案:擴(kuò)分區(qū)。
3.1.1 通過Kafka-manager
Step1:在Kafka-manager的topic列表,點(diǎn)擊具體的topic,進(jìn)入詳情頁面,點(diǎn)擊[add Partitions],如圖所示:
Step2:點(diǎn)擊增加分區(qū),彈出如下框:
說明如下:
- Partitions
擴(kuò)容后的總分區(qū)個數(shù),并不是本次增加的分區(qū)個數(shù)。 - Brokers
分區(qū)需要分布的Broker,建議全選,充分利用整個集群的性能。
3.1.2 運(yùn)維命令
可以通過Kafka提供的kafka-topics命令,修改topic的分區(qū),具體參考如下:
溫馨提示: 對這些運(yùn)維命令不熟悉沒關(guān)系,基本都提供了–help
3.2 分區(qū)移動
由于存在大量的只有一個分區(qū)的topic,并且這些topic都分布到了第一個節(jié)點(diǎn),是不是可以將某些topic的分區(qū)移動到其他節(jié)點(diǎn)呢?
接下來介紹一下分區(qū)移動如何操作。
3.2.1 kafka-manager
Step1:進(jìn)入topic詳情頁面,點(diǎn)擊[Generate Partition Assignments],如下圖所示:
Step2:進(jìn)入頁面后,選擇需要遷移到的brroker,還可以改變topic的副本因子,最后點(diǎn)擊[Generate Partition Assignments],如下圖所示:
Step3:點(diǎn)擊完成后,此時只是生成了分區(qū)遷移計劃,并沒有真正的執(zhí)行,需要點(diǎn)擊[Reassign Parttions]按鈕。
3.2.2 運(yùn)維命令
Step1:首先我們需要準(zhǔn)備需要執(zhí)行遷移的topic信息,例如將如下信息保存在文件dw_test_kafka_040802-topics-to-move.json中。
{"topics":[{"topic":"dw_test_kafka_040802"}],"version": 1 }Step2:使用kafka提供的kafka-reassign-partitions.sh命令生成執(zhí)行計劃
上面的參數(shù)其實(shí)對照kafka-manager的圖理解起來會更快,點(diǎn)出如下關(guān)鍵點(diǎn):
- –broker-list
分區(qū)需要分布的broker。如果多個,使用雙引號,例如 “0,1,2”。 - –topics-to-move-json-file
需要執(zhí)行遷移的topic列表。 - –generate
表示生成執(zhí)行計劃(并不真正執(zhí)行)
執(zhí)行成功后會輸出當(dāng)前的分區(qū)分布計劃與新的執(zhí)行計劃,通常我們可以先將當(dāng)前的執(zhí)行計劃存儲到一個備份目錄中,將新生成的計劃存儲到一個文件中。
Step3:使用kafka提供的kafka-reassign-partitions.sh命令執(zhí)行分區(qū)遷移計劃
其關(guān)鍵點(diǎn)如下:
- –reassignment-json-file
指定上一步驟生成的執(zhí)行計劃。
執(zhí)行成功過后輸出Successfully,重分區(qū)是一個非常復(fù)雜的過程,命令執(zhí)行完成后,并不會真正執(zhí)行完成,可以通過查詢主題的詳細(xì)信息來判斷是否真正遷移成功。
4、進(jìn)階
通過kafka-reassign-partitions.sh對分區(qū)進(jìn)行遷移,會影響業(yè)務(wù)方的正常使用嗎?即會影響消息的消費(fèi)與發(fā)送嗎?
作為一名架構(gòu)師,特別是對中間件做變更時,考慮對業(yè)務(wù)的影響范圍是必備的一步,直接影響到實(shí)施的復(fù)雜度。
我們需要對分區(qū)遷移的實(shí)現(xiàn)原理做進(jìn)一步探究,本文暫不從源碼角度詳細(xì)剖析,只是舉例闡述一下分區(qū)遷移的實(shí)現(xiàn)機(jī)制。
需求:一個TopicA的其中一個分區(qū)p0,分布在broker id為1,2,3上,目前要將其遷移到brokerId為4,5,6。
在介紹遷移過程之前,我們先定義三個變量:
- OAR
遷移前分區(qū)的分布情況。 - RAR
遷移后的分區(qū)分布情況 - AR
當(dāng)前運(yùn)行過程中的分區(qū)分布情況
結(jié)合上述例子,其整個遷移步驟如下:
| {1,2,3} | 1{1,2,3} | |
| {1,2,3,4,5,6} | 1{1,2,3} | 首先基于RAR集合(遷移后的新broker)上創(chuàng)建對應(yīng)的分區(qū),并開始從Leader同步數(shù)據(jù) |
| {1,2,3,4,5,6} | 1{1,2,3,4,5,6} | 新創(chuàng)建的副本追上主節(jié)點(diǎn)的進(jìn)度,并進(jìn)入ISR集合 |
| {1,2,3,4,5,6} | 4{1,2,3,4,5,6} | 如果Leader不在RAR所在的集合中,則發(fā)起一次選舉,將Leader變更為RAR中其中一臺。 |
| {1,2,3,4,5,6} | 4{4,5,6} | 將OAR中的副本狀態(tài)設(shè)置為OfflineReplica(下線),將其從ISR中剔除 |
| {4,5,6} | 4{4,5,6} | 刪除下線的副本,完成整個遷移操作 |
從上面這個過程,只有在Leader選舉期間會對消息發(fā)送、消息消費(fèi)造成影響,但通過Zookeeper實(shí)現(xiàn)Leader選舉可在秒級別響應(yīng),結(jié)合Kafka消息發(fā)送端的緩沖隊(duì)列、重試機(jī)制,在理論上可以做到對業(yè)務(wù)無影響。
好了,本文就介紹到這里了,一鍵三連(關(guān)注、點(diǎn)贊、留言)是對我最大的鼓勵。
掌握一到兩門java主流中間件,是敲開BAT等大廠必備的技能,送給大家一個Java中間件學(xué)習(xí)路線,助力大家實(shí)現(xiàn)職場的蛻變。
Java進(jìn)階之梯,成長路線與學(xué)習(xí)資料,助力突破中間件領(lǐng)域
最后分享筆者一個硬核的RocketMQ電子書,您將獲得千億級消息流轉(zhuǎn)的運(yùn)維經(jīng)驗(yàn)。
獲取方式:私信回復(fù)RMQPDF即可獲取。
個人網(wǎng)站:https://www.codingw.net
總結(jié)
以上是生活随笔為你收集整理的通过一个Kafka故障解决过程阐述架构师必须具备的架构思维的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深入理解Linux网络技术内幕学习笔记第
- 下一篇: 【转】objective-c基本数据类型