【kafka實戰】分割槽重分配可能出現的問題和排查問題思路(生產環境實戰,乾貨!!!非常幹!!!建議收藏)
@
目錄推薦一款非常好用的kafka管理平臺,kafka的靈魂伴侶
滴滴開源LogiKM一站式Kafka監控與管控平臺
這篇文章源自於,一位群友的問題,然後就寫下了這篇文章
進群加V :jjdlmn_先定義一下名詞: 遷移前的Broker: OriginBroker 、 遷移後的副本 TargetBroker
前提
在這之前如果你比較瞭解 分割槽重分配的原理 的話,下面的可能更好理解;
推薦你閱讀一下下面幾篇文章(如果你點不進去說明我還沒有釋出)
【kafka原始碼】ReassignPartitionsCommand原始碼分析(副本擴縮、資料遷移、副本重分配、副本跨路徑遷移)
【kafka運維】副本擴縮容、資料遷移、副本重分配、副本跨路徑遷移
Kafka的靈魂伴侶Logi-KafkaManger(4)之運維管控–叢集運維(資料遷移和叢集線上升級)
如果你不想費那個精力,那直接看下面我畫的這張圖,你自己也能分析出來可能出現的問題;以及怎麼排查
所有異常情況
1. TargetBroker若不線上,遷移指令碼執行會失敗
TargetBroker若不線上
, 在開始執行任務指令碼的時候,校驗都不會被通過呢
情景演示
BrokerId | 角色 | 狀態 | 副本 |
---|---|---|---|
0 | 普通Broker | 正常 | test-0 |
1 | 普通Broker | 宕機 | 無 |
現在將分割槽topic-test-0
從Broker0 遷移到 Broker1
sh bin/kafka-reassign-partitions.sh --zookeeper xxxxxx:2181/kafka3 --reassignment-json-file config/reassignment-json-file.json --execute --throttle 1000000
執行異常
Partitions reassignment failed due to The proposed assignment contains non-existent brokerIDs: 1
kafka.common.AdminCommandFailedException: The proposed assignment contains non-existent brokerIDs: 1
at kafka.admin.ReassignPartitionsCommand$.parseAndValidate(ReassignPartitionsCommand.scala:348)
at kafka.admin.ReassignPartitionsCommand$.executeAssignment(ReassignPartitionsCommand.scala:209)
at kafka.admin.ReassignPartitionsCommand$.executeAssignment(ReassignPartitionsCommand.scala:205)
at kafka.admin.ReassignPartitionsCommand$.main(ReassignPartitionsCommand.scala:65)
at kafka.admin.ReassignPartitionsCommand.main(ReassignPartitionsCommand.scala)
2. TargetBroker在開始遷移過程中宕機,導致遷移任務一直在進行中
一般這種情況是出現在, 寫入了節點
/admin/reassign_partitions/
之後, 有一臺/N臺targetBroker
中途宕機了, 導致這臺Broker不能正常的建立新的副本和同步Leader操作,就不能夠繼續往後面走了
情景演示
模擬這種情況,我們可以手動寫入了節點/admin/reassign_partitions/
重分配資訊例如:
- 建立一個節點寫入的資訊如下, 其中Broker-1 不線上; 模擬在分配過程中宕機了;
{"version":1,"partitions":[{"topic":"test","partition":0,"replicas":[1]}]}
- 看到
/broker/topics/{topicName}
中的節點已經變更為下面的了 - 接下來應該要像Broker-1傳送
LeaderAndIsr
請求讓它建立副本並且同步Leader;但是這個時候Broker-1是不線上的狀態;所以就會導致 這個任務一直在進行中, 如果你想進行其他的重分配就會提示如下There is an existing assignment running.
解決方法
只要知道什麼情況,那解決問題思路就很清晰了, 只要把掛掉的Broker重啟就行了;
3. 被遷移副本沒有找到Leader,導致TargetReplica一直不能同步副本
只要被遷移的副本的Leader服務掛了,並且還沒有選舉出新的Leader, 那麼就沒地方同步了
這種情況跟 情況2類似,但也有不同, 不同在於 這裡可能是其他的Broker掛了導致的
情景演示
BrokerId | 角色 | 狀態 | 副本 |
---|---|---|---|
0 | 普通Broker | 正常 | 無 |
1 | 普通Broker | 宕機 | test-0 |
現在將分割槽test-0
從Broker1 遷移到 Broker0
{"version":1,"partitions":[{"topic":"test","partition":0,"replicas":[0],"log_dirs":["any"]}]}
看上面的圖, TargetReplica
會收到LeaderAndIsr
然後開始建立副本,並且zk中也寫入了TargetBroker
的AR資訊;
然後開始去同步Leader的副本資訊,這個時候Leader是誰? 是Broker-1上的test-0
;(只有一個副本),然後準備去同步的時候,OriginBroker
不線上,就同步不了,所以TargetReplica
只是建立了副本,但是還沒有同步資料;如下
TargetReplica
被建立,但是沒有資料; 又因為OriginBroker
不線上,所以也沒有被刪除副本(下圖kafka-logs-30 是Broker0;kafka-logs-31是Broker1)
- 因為整個分割槽重分配任務沒有完成,所以
/admin/reassign_partitions/
還未刪除
{"version":1,"partitions":[{"topic":"test","partition":0,"replicas":[0]}]}
- /broker/topics/{topicName} 中的節點會更新為下圖, 其中
AR
RR
都還沒有被清空
brokers/topics/test/partitions/0/state
節點 看Leader為-1,並且ISR中也沒有加入TargetBroker
只要是沒有同步成功,那麼整個分割槽流程就會一直進行中;
解決方案
一般出現這種情況還是少見的,基本上單副本才會出現這種情況
一般就算OriginBroker
掛了,導致一個副本下線了,那麼其他的副本會承擔起Leader的角色
如果只有一個副本,那麼就會造成這種異常情況了,這個時候只需要把OriginBroker
重啟一下就行了
4. 限流導致重分配一直完成不了
我們一般在做分割槽副本重分配任務的時候,一般都會加上一個限流值
--throttle
: 遷移過程Broker之間傳輸的速率,單位 bytes/sec
注意這個值是Broker之間的限流, 並不僅僅指的是這次遷移的幾個分割槽副本的限流;而是包含其他Topic自身正常的資料同步的流量; 所以如果你這個限流值設定的很小, 速率比正常情況下的同步速率還要小
又或者你的同步速率比建立訊息的速率都要慢, 那麼這個任務是永遠完不成的!
情景演示
- 建立重分配任務, 限流值 1
sh bin/kafka-reassign-partitions.sh --zookeeper xxxx:2181/kafka3 --reassignment-json-file config/reassignment-json-file.json --execute --throttle 1
- 基本上這個速率是別想完成了,
admin/reassign_partitions
節點一直在 - zk中的限流配置
解決方案
將限流閾值設定大一點,重新執行一下上面的指令碼,限流值加大
sh bin/kafka-reassign-partitions.sh --zookeeper xxxx:2181/kafka3 --reassignment-json-file config/reassignment-json-file.json --execute --throttle 100000000
(雖然這裡執行之後還是會提醒你有任務在進行中,但是會重寫限流資訊的)
千萬記得 任務結束要用 --verify
來把限流值移除掉! 不然他會一直存在的;
5. 資料量太大,同步的賊慢
出現這個情況是很常見的一個事情,它也不屬於異常, 效能問題你沒辦法,但是往往我們做資料遷移的時候會忽略一個問題; 那就是過期資料太多,遷移這個過期資料本身就沒有什麼意義;
可以看我之前的文章 Kafka的靈魂伴侶Logi-KafkaManger(4)之運維管控–叢集運維(資料遷移和叢集線上升級)
減少遷移的有效資料,能夠大大增加資料遷移的效率;
解決方案
減少遷移的資料量
如果要遷移的Topic 有大量資料(Topic 預設保留7天的資料),可以在遷移之前臨時動態地調整retention.ms 來減少資料量;
當然手動的來做這個操作真的是太讓你煩心了, 你可以有更聰明的選擇
Kafka的靈魂伴侶Logi-KafkaManger(4)之運維管控–叢集運維(資料遷移和叢集線上升級)
視覺化的進行資料遷移、分割槽副本重分配;
設定限流、減小資料遷移量、遷移完成自動清理限流資訊
排查問題思路
上面我把我能想到的所有可能出現的問題解決方案都列舉了出來; 那麼碰到了
重分配任務一直在進行中怎麼快速定位和解決呢?There is an existing assignment running.
1. 先看/admin/reassign_partitions裡面的資料
假設一次任務如下; 有兩個分割槽 test-0分割槽分在Broker[0,1] test-1分割槽在Broker[0,2]
{"version":1,"partitions":[{"topic":"test","partition":0,"replicas":[0,1]},
{"topic":"test","partition":1,"replicas":[0,2]}]}
恰好圖中Broker1宕機了,test-0
就不能完成了,test-1
則正常完成; 那麼這個時候/admin/reassign_partitions
節點就是
{"version":1,"partitions":[{"topic":"test","partition":0,"replicas":[0,1]}]}
所以我們先看節點的資料,能夠讓我們指定 是哪個分割槽重分割槽出現了問題 ;
從上面資料可以指定, test-0
這個分割槽沒有完成,對應的Broker有 [0,1]
2. 再看brokers/topics/{TopicName}/partitions/{分割槽號}/state資料
通過步驟1 我知道 test-0
有問題,我就直接看節點/brokers/topics/test/partitions/0/state
得到資料
這裡分兩種情況看
-
如下
{"controller_epoch":28,"leader":0,"version":1,"leader_epoch":2,"isr":[0]}
可以發現 ISR:[0], 只有0 ; 正常來說應該是我上面設定的[0,1]; 那問題就定位在 Broker-1中的副本沒有加入到ISR中;
接下來的問題就是排查為啥Broker-1 沒有加入到ISR了; -
如下, leader:-1 的情況
{"controller_epoch":28,"leader":-1,"version":1,"leader_epoch":2,"isr":[0]}
leader:-1 表示當前沒有Leader; 新增的副本沒有地方去同步資料,就很迷茫;
所以接下來要排查的就是其該TopicPartition的其他副本所在Broker是不是都宕機了; 如何確定其他Broker?
看AR是否都正常;AR資料在brokers/topics/{topicName}
可以看到 ;當然你可以通過 滴滴開源-LogIKM 一站式Kafka監控與管控平臺 更簡單的去排查這個步驟;如下
3. 根據步驟2確定對應的Broker是否異常
如果找到有Broker異常,直接重啟就完事了;
4.查詢限流大小
如果步驟3還沒有解決問題,也沒有Broker異常,那麼再判斷一下流量限制的問題了
-
首先看看節點
/config/brokers/{brokerId}
是否配置了限流資訊;
-
還有節點
/config/topics/{topicName}
的資訊
-
並且看到Broker節點也沒有加入到ISR, 那麼妥妥的同步速率問題了
-
如果查詢到的限流值比較小的話,可以適當的調大一點
sh bin/kafka-reassign-partitions.sh --zookeeper xxxx:2181/kafka3 --reassignment-json-file config/reassignment-json-file.json --execute --throttle 100000000
5. 重新執行重分配任務(停止之前的任務)
如果上面還是沒有解決問題,那麼可能是你副本資料量太大,遷移的資料太多, 或者你TargetBroker網路情況不好等等,網路傳輸已經達到上限,這屬於效能瓶頸的問題了,或許你該考慮一下 是不是重新分配一下;或者找個夜深人靜的晚上做重分配的操作;
情景演示
-
test-0 分割槽 原本只在Broker [0]中, 現在重分配到 [0,1], 用
--throttle 1
模擬一下網路傳輸速率慢, 效能瓶頸等
這個節點一直會存在,一直在進行中,
adding_replicas
也一直顯示[1] -
同時可以看到 Broker-1 是存活的
-
但是不在ISR裡面的
-
判斷出來 可能同步速率更不上, TargetBroker可能網路狀況不好,或者本身壓力也挺大; 換個TargetBroker
-
直接刪除節點
/admin/reassign_partitions
,然後重新執行一下重分配任務; 重分配到[0,2]中{"version":1,"partitions":[{"topic":"test","partition":0,"replicas":[0,2]}]}
可以看到已經在zk中寫入了新的分配情況;
但是topic節點中卻沒有變更AR
和ARS
這是因為Controller
雖然收到了節點的新增通知/admin/reassign_partitions
; 但是在校驗的時候,它記憶體裡面儲存過之前的重分配任務,所以對Controller而言,它認為之前的任務還是沒有正常結束的,所以也就不會走後門的流程; -
重新選舉Controller角色,重新載入
/admin/reassign_partitions
; 我在文章【kafka原始碼】Controller啟動過程以及選舉流程原始碼分析裡面分析過,Controller重新選舉會重新載入/admin/reassign_partitions
節點並繼續任務的執行; 切換之後如下,變更正常
切換Controller,需要你主動去刪除zk節點 /controller
當然還有更簡單的方式 滴滴開源LogiKM 一站式Kafka監控與管控平臺 如下
指定一些空閒的Broker當做Controller,並立即切換是一個明智的選擇;
解決方案
-
資料量太大是因為很多過期資料; 如果你重分配的時候沒有考慮清理過期資料; 那麼就重新分配把
但是重分配任務同一時間只能有一個,所以你只能暴力刪除/admin/reassign_partitions
;然後重新分配一下;
注意重新分配的時候,請務必設定臨時的資料過期時間,減少遷移資料; 並且還要讓Controller
切換一下; -
總結起來是
①. 刪除節點/admin/reassign_partitions
②. 重新執行重分配任務
③. 讓Controller
發生重選舉
排查工具+思考
分析完上面的問題, 起始這個問題排查起來,還是挺麻煩的,看這個看那個指標什麼的;
是不是可以有一個工具來自動幫我 排查問題+提供解決方案;
既然排查思路有了,視覺化,自動化,工具化 也不是什麼難事吧;
所以我在 滴滴開源LogiKM 一站式Kafka監控與管控平臺 上準備提一個ISSUE, 來簡單的實現這麼一個功能;
看什麼時候比較空的時候來完成它,你要是有興趣,也可以一起來完成它!
現實案例分析
週五快下班的時候, 群裡面有個同學問了一句下面這個問題, 然後我就我回復了一下;
後來為了具體分析就拉了一個小群來尋找蛛絲馬跡
具體的日誌我就不貼出來了,太多了;
這位同學在 進行分割槽重分配的過程中, 持久了很久,一直在進行中, 後來去百度 說讓在zk中刪除 重分配任務節點;
我告知了節點之後,然後立馬刪除了這個節點,後來發現某一臺遷移的 TargetBroker掛了, 讓他們重啟之後,重分配的任務仍舊接著進行下去了, 也就是說 TargetBroker
依然正常的完成了副本的分配;
問題分析
其實這個問題就是我們上面分析過的 第二種情況 2. TargetBroker在開始遷移過程中宕機,導致遷移任務一直在進行中
具體為什麼TargetBroker為什麼會宕機 這不是我們分析的範疇;
因為TargetBroker
宕機了,導致任務不能結束; 這個時候只需要重啟TargetBroker
就可以了;
雖然他們直接暴力刪除了節點/admin/reassign_partitions
; 問題也不大;
影響點在下一次開始重分配的任務時候, Controller
記憶體裡面還是報錯的之前的資訊,所以下一次的任務不會被執行;
但是如果你讓Controller
重新分配之後,那麼就會繼續執行了,沒有什麼影響;
雖然他們這次刪除了節點, 也裡面開始了下一次的分配; 但是因為它重啟了 TargetBroker
;讓原來的任務順利的進行了下去; 哪怕沒有切換Controller
, 也是不會影響下一次的重分配任務的;(因為順利進行 Controller被通知的之前的已經結束了)
如果你有其他可能出現的異常,或者其他有關於kafka、es、agent等等相關問題,請聯絡我,我會補充這篇文章
歡迎Star和共建由滴滴開源的kafka的管理平臺,非常優秀非常好用的一款kafka管理平臺
滿足所有開發運維日常需求