圖解 kafka 的高可用機制

      網友投稿 679 2025-03-31

      對于一個復雜的分布式系統,如果沒有豐富的經驗和牛逼的架構能力,很難把系統做得簡單易維護,我們都知道,一個軟件的生命周期中,后期維護占了70%,所以系統的可維護性是極其重要的, Kafka 能成為大數據領域的事實標準,很大原因是因為運維起來很方便簡單,今天我們來看下 Kafka 是怎么來簡化運維操作的。

      kafka 使用多副本來保證消息不丟失,多副本就涉及到kafka的復制機制,在一個超大規模的集群中,時不時地這個點磁盤壞了,那個點cpu負載高了,出現各種各樣的問題,多個副本之間的復制,如果想完全自動化容錯,就要做一些考量和取舍了。我們舉個例子說明下運維中面對的復雜性,我們都知道 kafka 有個 ISR集合,我先說明下這個概念:

      kafka不是完全同步,也不是完全異步,是一種ISR機制:

      leader會維護一個與其基本保持同步的Replica列表,該列表稱為ISR(in-sync Replica),每個Partition都會有一個ISR,而且是由leader動態維護

      如果一個follower比一個leader落后太多,或者超過一定時間未發起數據復制請求,則leader將其重ISR中移除

      當ISR中所有Replica都向Leader發送ACK時,leader才commit,這時候producer才能認為一個請求中的消息都commit了。

      在這種機制下, 如果一個 producer 一個請求發送的消息條數太多,導致flower瞬間落后leader太多怎么辦?如果 follower不停的移入移出 ISR 會不會影響性能?如果對這種情況加了報警,就有可能造成告警轟炸,如果我們不加報警,如果是broker 掛掉或者 broker 因為IO性能或者GC問題夯住的情況導致落后leader太多,這種真正需要報警情況怎么辦呢? 今天我們來看下 kafka 是怎么在設計上讓我們完全避免這種運維中頭疼的問題的。

      kafka的復制機制

      kafka 每個分區都是由順序追加的不可變的消息序列組成,每條消息都一個唯一的offset 來標記位置。

      kafka中的副本機制是以分區粒度進行復制的,我們在kafka中創建 topic的時候,都可以設置一個復制因子,這個復制因子決定著分區副本的個數,如果leader 掛掉了,kafka 會把分區主節點failover到其他副本節點,這樣就能保證這個分區的消息是可用的。leader節點負責接收producer 打過來的消息,其他副本節點(follower)從主節點上拷貝消息。

      kakfa 日志復制算法提供的保證是當一條消息在 producer 端認為已經 committed的之后,如果leader 節點掛掉了,其他節點被選舉成為了 leader 節點后,這條消息同樣是可以被消費到的。

      這樣的話,leader 選舉的時候,只能從 ISR集合中選舉,集合中的每個點都必須是和leader消息同步的,也就是沒有延遲,分區的leader 維護ISR 集合列表,如果某個點落后太多,就從 ISR集合中踢出去。 producer 發送一條消息到leader節點后, 只有當ISR中所有Replica都向Leader發送ACK確認這條消息時,leader才commit,這時候producer才能認為這條消息commit了,正是因為如此,kafka客戶端的寫性能取決于ISR集合中的最慢的一個broker的接收消息的性能,如果一個點性能太差,就必須盡快的識別出來,然后從ISR集合中踢出去,以免造成性能問題。

      一個副本怎么才算是跟得上leader的副本

      一個副本不能 “caught up” leader 節點,就有可能被從 ISR集合中踢出去,我們舉個例子來說明,什么才是真正的 “caught up” —— 跟leader節點消息同步。

      kafka 中的一個單分區的 topic — foo,復制因子為 3 ,分區分布和 leader 和 follower 如下圖,現在broker 2和3 是 follower 而且都在 ISR 集合中。我們設置 replica.lag.max.messages 為4,只要 follower 只要不落后leader 大于3條消息,就然后是跟得上leader的節點,就不會被踢出去, 設置 replica.lag.time.max.ms 為 500ms, 意味著只要 follower 在每 500ms內發送fetch請求,就不會被認為已經dead ,不會從ISR集合中踢出去。

      現在 producer 發送一條消息,offset 為3, 這時候 broker 3 發生了 GC, 入下圖:

      因為 broker 3 現在在 ISR 集合中, 所以要么 broker 3 拉取同步上這條 offset 為3 的消息,要么 3 被從 ISR集合中踢出去,不然這條消息就不會 committed, 因為 replica.lag.max.messages=4 為4, broker 3 只落后一條消息,不會從ISR集合中踢出去, broker 3 如果這時候 GC 100ms, GC 結束,然后拉取到 offset 為3的消息,就再次跟 leader 保持完全同步,整個過程一直在 ISR集合中,如下圖:

      什么時候一個副本才會從ISR集合中踢出去

      一個副本被踢出 ISR集合的幾種原因:

      一個副本在一段時間內都沒有跟得上 leader 節點,也就是跟leader節點的差距大于 replica.lag.max.messages , 通常情況是 IO性能跟不上,或者CPU 負載太高,導致 broker 在磁盤上追加消息的速度低于接收leader 消息的速度。

      一個 broker 在很長時間內(大于 replica.lag.time.max.ms )都沒有向 leader 發送fetch 請求, 可能是因為 broker 發生了 full GC, 或者因為別的原因掛掉了。

      一個新 的 broker 節點,比如同一個 broker id, 磁盤壞掉,新換了一臺機器,或者一個分區 reassign 到一個新的broker 節點上,都會從分區leader 上現存的最老的消息開始同步。

      所以說 kafka 0.8 版本后設置了兩個參數 , replica.lag.max.messages 用來識別性能一直很慢的節點, replica.lag.time.max.ms 用來識別卡住的節點。

      一個節點在什么情況下真正處于落后狀態

      從上面的情況來看,兩個參數看似已經足夠了,如果一個副本超過 replica.lag.time.max.ms 還沒有發送fetch同步請求, 可以認為這個副本節點卡住了,然后踢出去,但是還有一種比較特殊的情況沒有考慮到,我們上文中設置 replica.lag.max.messages 為4,之所以設置為 4, 是我們已經知道 producer 每次請求打過來的消息數都在 4 以下,如果我們的參數是作用于多個 topic 的情況,那么這個 producer 最大打過來的消息數目就不好估計了,或者說在經常出現流量抖動的情況下,就會出現一個什么情況呢,我們還是使用例子說明:

      如果我們的 topic — foo 的 producer 因為流量抖動打過來一個 包含 4條消息的請求,我們設置的 replica.lag.max.messages 還是為4, 這個時候,所有的 follower 都會因為超出落后條數被踢出 ISR集合:

      然后,因為 follower 是正常的,所以下一次 fetch 請求就會又追上 leader, 這時候就會再次加入 ISR 集合,如果經常性的抖動,就會不斷的移入移出ISR集合,會造成令人頭疼的 告警轟炸。

      這里的核心問題是,在海量的 topic 情況下,或者經常性的流量抖動情況下,我們不能對 topic 的producer 每次打過來的消息數目做任何假設,所以就不太好定出來一個 合適的 eplica.lag.max.messages 值

      一個配置全部搞定

      圖解 kafka 的高可用機制

      其實只有兩種情況是異常的,一種就是卡住,另外一種是follower 性能慢,如果我們只根據 follower 落后 leader 多少來判斷是否應該把 follower 提出ISR集合,就必須要對流量進行預測估計,怎么才能避免這種不靠譜的估計呢,kafka 給出 的方案是這樣的,對 replica.lag.time.max.ms 這個配置的含義做了增強,和之前一樣,如果 follower 卡住超過這個時間不發送fetch請求, 會被踢出ISR集合,新的增強邏輯是,在 follower 落后 leader 超過 eplica.lag.max.messages 條消息的時候,不會立馬踢出ISR 集合,而是持續落后超過 replica.lag.time.max.ms 時間,才會被踢出 ,這樣就能避免流量抖動造成的運維問題,因為follower 在下一次fetch的時候就會跟上leader, 這樣就也不用對 topic 的寫入速度做任何的估計嘍。

      --------------------------------------

      本文轉自UMUTech博客51CTO博客

      Kafka

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:制作財務報表表格(寫財務報表)
      下一篇:excel中如何使sheet1和sheet2關聯?(如何使sheet1與sheet2相關聯)
      相關文章
      亚洲欧洲国产经精品香蕉网| 亚洲国产成人精品久久| 亚洲乱人伦中文字幕无码| 亚洲AV无码一区二区三区在线| 亚洲av日韩综合一区在线观看| 国产亚洲精品激情都市| 亚洲区不卡顿区在线观看| 夜色阁亚洲一区二区三区| 久久精品国产亚洲av品善| 亚洲av日韩av永久无码电影 | 亚洲视频无码高清在线| 亚洲一级毛片中文字幕| 亚洲国产精品人久久电影| 亚洲成人在线免费观看| 亚洲香蕉久久一区二区| 国产精品亚洲四区在线观看| 国产精品亚洲四区在线观看| 亚洲日本一线产区和二线产区对比| 中文字幕在线观看亚洲视频| 中文字幕乱码亚洲无线三区| 亚洲精品V天堂中文字幕| 国产成人高清亚洲一区久久| 亚洲成人影院在线观看| 亚洲一区二区三区在线视频| 亚洲中文字幕在线乱码| 亚洲国产精品无码久久久不卡| 亚洲AV无码欧洲AV无码网站| 内射干少妇亚洲69XXX| 亚洲国产成人精品无码区在线秒播 | 爱爱帝国亚洲一区二区三区| 国产成人va亚洲电影| 亚洲伊人久久成综合人影院| 国产亚洲综合久久系列| 亚洲91av视频| 亚洲国产精品yw在线观看| 亚洲欧美精品午睡沙发| 亚洲av片在线观看| 超清首页国产亚洲丝袜| 亚洲AV无码欧洲AV无码网站| 亚洲激情校园春色| 亚洲成av人片在www鸭子|