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