1. 程式人生 > 其它 >【kafka實戰】分割槽重分配可能出現的問題和排查問題思路(生產環境實戰,乾貨!!!非常幹!!!建議收藏)

【kafka實戰】分割槽重分配可能出現的問題和排查問題思路(生產環境實戰,乾貨!!!非常幹!!!建議收藏)

@

目錄

推薦一款非常好用的kafka管理平臺,kafka的靈魂伴侶

滴滴開源LogiKM一站式Kafka監控與管控平臺


這篇文章源自於,一位群友的問題,然後就寫下了這篇文章

進群加V :jjdlmn_

Kafka專欄整理地址 請戳這裡0.0

先定義一下名詞: 遷移前的Broker: OriginBroker 、 遷移後的副本 TargetBroker

前提

在這之前如果你比較瞭解 分割槽重分配的原理 的話,下面的可能更好理解;
推薦你閱讀一下下面幾篇文章(如果你點不進去說明我還沒有釋出)

【kafka原始碼】ReassignPartitionsCommand原始碼分析(副本擴縮、資料遷移、副本重分配、副本跨路徑遷移)


【kafka運維】副本擴縮容、資料遷移、副本重分配、副本跨路徑遷移

Kafka的靈魂伴侶Logi-KafkaManger(4)之運維管控–叢集運維(資料遷移和叢集線上升級)

如果你不想費那個精力,那直接看下面我畫的這張圖,你自己也能分析出來可能出現的問題;以及怎麼排查

所有異常情況

Kafka專欄整理地址 請戳這裡

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在開始遷移過程中宕機,導致遷移任務一直在進行中

Kafka專欄整理地址 請戳這裡

一般這種情況是出現在, 寫入了節點/admin/reassign_partitions/之後, 有一臺/N臺 targetBroker 中途宕機了, 導致這臺Broker不能正常的建立新的副本和同步Leader操作,就不能夠繼續往後面走了

情景演示

模擬這種情況,我們可以手動寫入了節點/admin/reassign_partitions/重分配資訊例如:

  1. 建立一個節點寫入的資訊如下, 其中Broker-1 不線上; 模擬在分配過程中宕機了;
{"version":1,"partitions":[{"topic":"test","partition":0,"replicas":[1]}]}
  1. 看到 /broker/topics/{topicName} 中的節點已經變更為下面的了
  2. 接下來應該要像Broker-1傳送LeaderAndIsr請求讓它建立副本並且同步Leader;但是這個時候Broker-1是不線上的狀態;所以就會導致 這個任務一直在進行中, 如果你想進行其他的重分配就會提示如下
    There is an existing assignment running.
    

解決方法

只要知道什麼情況,那解決問題思路就很清晰了, 只要把掛掉的Broker重啟就行了;

3. 被遷移副本沒有找到Leader,導致TargetReplica一直不能同步副本

Kafka專欄整理地址 請戳這裡

只要被遷移的副本的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只是建立了副本,但是還沒有同步資料;如下

  1. TargetReplica被建立,但是沒有資料; 又因為OriginBroker不線上,所以也沒有被刪除副本(下圖kafka-logs-30 是Broker0;kafka-logs-31是Broker1)
  2. 因為整個分割槽重分配任務沒有完成,所以 /admin/reassign_partitions/還未刪除

{"version":1,"partitions":[{"topic":"test","partition":0,"replicas":[0]}]}

  1. /broker/topics/{topicName} 中的節點會更新為下圖, 其中AR RR都還沒有被清空
  2. brokers/topics/test/partitions/0/state節點 看Leader為-1,並且ISR中也沒有加入 TargetBroker

    只要是沒有同步成功,那麼整個分割槽流程就會一直進行中;

解決方案

一般出現這種情況還是少見的,基本上單副本才會出現這種情況
一般就算OriginBroker掛了,導致一個副本下線了,那麼其他的副本會承擔起Leader的角色
如果只有一個副本,那麼就會造成這種異常情況了,這個時候只需要把OriginBroker重啟一下就行了

4. 限流導致重分配一直完成不了

Kafka專欄整理地址 請戳這裡

我們一般在做分割槽副本重分配任務的時候,一般都會加上一個限流值
--throttle : 遷移過程Broker之間傳輸的速率,單位 bytes/sec
注意這個值是Broker之間的限流, 並不僅僅指的是這次遷移的幾個分割槽副本的限流;而是包含其他Topic自身正常的資料同步的流量; 所以如果你這個限流值設定的很小, 速率比正常情況下的同步速率還要小
又或者你的同步速率比建立訊息的速率都要慢, 那麼這個任務是永遠完不成的!

情景演示

  1. 建立重分配任務, 限流值 1
     sh bin/kafka-reassign-partitions.sh --zookeeper xxxx:2181/kafka3 --reassignment-json-file config/reassignment-json-file.json  --execute --throttle 1 
    
  2. 基本上這個速率是別想完成了,admin/reassign_partitions節點一直在
  3. 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專欄整理地址 請戳這裡

出現這個情況是很常見的一個事情,它也不屬於異常, 效能問題你沒辦法,但是往往我們做資料遷移的時候會忽略一個問題; 那就是過期資料太多,遷移這個過期資料本身就沒有什麼意義;
可以看我之前的文章 Kafka的靈魂伴侶Logi-KafkaManger(4)之運維管控–叢集運維(資料遷移和叢集線上升級)

減少遷移的有效資料,能夠大大增加資料遷移的效率;

解決方案

減少遷移的資料量
如果要遷移的Topic 有大量資料(Topic 預設保留7天的資料),可以在遷移之前臨時動態地調整retention.ms 來減少資料量;
當然手動的來做這個操作真的是太讓你煩心了, 你可以有更聰明的選擇

Kafka的靈魂伴侶Logi-KafkaManger(4)之運維管控–叢集運維(資料遷移和叢集線上升級)

滴滴開源Logi-KM一站式Kafka監控與管控平臺

視覺化的進行資料遷移、分割槽副本重分配;

設定限流、減小資料遷移量、遷移完成自動清理限流資訊

排查問題思路

Kafka專欄整理地址 請戳這裡

上面我把我能想到的所有可能出現的問題解決方案都列舉了出來; 那麼碰到了
重分配任務一直在進行中怎麼快速定位和解決呢?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得到資料
這裡分兩種情況看

  1. 如下

    {"controller_epoch":28,"leader":0,"version":1,"leader_epoch":2,"isr":[0]}
    

    可以發現 ISR:[0], 只有0 ; 正常來說應該是我上面設定的[0,1]; 那問題就定位在 Broker-1中的副本沒有加入到ISR中;
    接下來的問題就是排查為啥Broker-1 沒有加入到ISR了;

  2. 如下, 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異常,那麼再判斷一下流量限制的問題了

  1. 首先看看節點/config/brokers/{brokerId} 是否配置了限流資訊;

  2. 還有節點/config/topics/{topicName}的資訊

  3. 並且看到Broker節點也沒有加入到ISR, 那麼妥妥的同步速率問題了

  4. 如果查詢到的限流值比較小的話,可以適當的調大一點

    
    	 sh bin/kafka-reassign-partitions.sh --zookeeper xxxx:2181/kafka3 --reassignment-json-file config/reassignment-json-file.json  --execute --throttle 100000000
    	  
    

5. 重新執行重分配任務(停止之前的任務)

如果上面還是沒有解決問題,那麼可能是你副本資料量太大,遷移的資料太多, 或者你TargetBroker網路情況不好等等,網路傳輸已經達到上限,這屬於效能瓶頸的問題了,或許你該考慮一下 是不是重新分配一下;或者找個夜深人靜的晚上做重分配的操作;

情景演示

  1. test-0 分割槽 原本只在Broker [0]中, 現在重分配到 [0,1], 用--throttle 1 模擬一下網路傳輸速率慢, 效能瓶頸等

    這個節點一直會存在,一直在進行中,adding_replicas 也一直顯示[1]

  2. 同時可以看到 Broker-1 是存活的

  3. 但是不在ISR裡面的

  4. 判斷出來 可能同步速率更不上, TargetBroker可能網路狀況不好,或者本身壓力也挺大; 換個TargetBroker

  5. 直接刪除節點/admin/reassign_partitions ,然後重新執行一下重分配任務; 重分配到[0,2]中

    {"version":1,"partitions":[{"topic":"test","partition":0,"replicas":[0,2]}]}
    


    可以看到已經在zk中寫入了新的分配情況;
    但是topic節點中卻沒有變更AR ARS

    這是因為Controller雖然收到了節點的新增通知/admin/reassign_partitions; 但是在校驗的時候,它記憶體裡面儲存過之前的重分配任務,所以對Controller而言,它認為之前的任務還是沒有正常結束的,所以也就不會走後門的流程;

  6. 重新選舉Controller角色,重新載入/admin/reassign_partitions ; 我在文章【kafka原始碼】Controller啟動過程以及選舉流程原始碼分析裡面分析過,Controller重新選舉會重新載入/admin/reassign_partitions節點並繼續任務的執行; 切換之後如下,變更正常

    切換Controller,需要你主動去刪除zk節點 /controller
    當然還有更簡單的方式 滴滴開源LogiKM 一站式Kafka監控與管控平臺 如下

    指定一些空閒的Broker當做Controller,並立即切換是一個明智的選擇;

解決方案

  1. 資料量太大是因為很多過期資料; 如果你重分配的時候沒有考慮清理過期資料; 那麼就重新分配把
    但是重分配任務同一時間只能有一個,所以你只能暴力刪除/admin/reassign_partitions ;然後重新分配一下;
    注意重新分配的時候,請務必設定臨時的資料過期時間,減少遷移資料; 並且還要讓Controller切換一下;

  2. 總結起來是
    ①. 刪除節點/admin/reassign_partitions
    ②. 重新執行重分配任務
    ③. 讓Controller發生重選舉

排查工具+思考

Kafka專欄整理地址 請戳這裡

分析完上面的問題, 起始這個問題排查起來,還是挺麻煩的,看這個看那個指標什麼的;
是不是可以有一個工具來自動幫我 排查問題+提供解決方案;
既然排查思路有了,視覺化,自動化,工具化 也不是什麼難事吧;
所以我在 滴滴開源LogiKM 一站式Kafka監控與管控平臺 上準備提一個ISSUE, 來簡單的實現這麼一個功能;
看什麼時候比較空的時候來完成它,你要是有興趣,也可以一起來完成它!

現實案例分析

週五快下班的時候, 群裡面有個同學問了一句下面這個問題, 然後我就我回復了一下;
後來為了具體分析就拉了一個小群來尋找蛛絲馬跡

進群加V: jjdlmn_
具體的日誌我就不貼出來了,太多了;

這位同學在 進行分割槽重分配的過程中, 持久了很久,一直在進行中, 後來去百度 說讓在zk中刪除 重分配任務節點;
我告知了節點之後,然後立馬刪除了這個節點,後來發現某一臺遷移的 TargetBroker掛了, 讓他們重啟之後,重分配的任務仍舊接著進行下去了, 也就是說 TargetBroker 依然正常的完成了副本的分配;

問題分析

其實這個問題就是我們上面分析過的 第二種情況 2. TargetBroker在開始遷移過程中宕機,導致遷移任務一直在進行中
具體為什麼TargetBroker為什麼會宕機 這不是我們分析的範疇;

因為TargetBroker宕機了,導致任務不能結束; 這個時候只需要重啟TargetBroker就可以了;

雖然他們直接暴力刪除了節點/admin/reassign_partitions ; 問題也不大;
影響點在下一次開始重分配的任務時候, Controller記憶體裡面還是報錯的之前的資訊,所以下一次的任務不會被執行;
但是如果你讓Controller重新分配之後,那麼就會繼續執行了,沒有什麼影響;

雖然他們這次刪除了節點, 也裡面開始了下一次的分配; 但是因為它重啟了 TargetBroker ;讓原來的任務順利的進行了下去; 哪怕沒有切換Controller, 也是不會影響下一次的重分配任務的;(因為順利進行 Controller被通知的之前的已經結束了)

如果你有其他可能出現的異常,或者其他有關於kafka、es、agent等等相關問題,請聯絡我,我會補充這篇文章


歡迎Star共建滴滴開源的kafka的管理平臺,非常優秀非常好用的一款kafka管理平臺
滿足所有開發運維日常需求

滴滴開源LogiKM 一站式Kafka監控與管控平臺


Kafka專欄整理地址 請戳這裡