日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

1 前言

本文里面涉及到較多基礎概念,如果忘記了,那么可以去看下《一文帶你快速入門kafka》。
對于一個消息中間件而言,可靠性是是至關重要的要素之一。不管是面試或者實際工作中,我們都不得不面對幾個問題:是幾個九?消息會不會丟失?如何保證冪等?如何順序消費?在這篇文章中,筆者會和大家一起去看 Kafka 是如何設計的。

2 可靠性分析

針對上面的幾個問題,Kafka 需要考慮包括并不限于以下問題:
  • 可用性
– Kafka 支持分布式架構,實現了故障轉移,避免單點問題
如何避免腦裂問題(這個要了解 Kafka 的 leader 選舉機制)
– 多副本機制,支持容災備份
  1. 數據一致性如何保證
  2. 數據同步要如何實現
  3. 消息問題
– 生產者投遞消息
broker回復投遞成功,但是消息丟失了。出現這種情況,一般是以下幾種情況:
  1. acks 配置成 0,生產者以為自己投遞成功了,但其實并沒有成功寫入 leader
  2. 消息持久化在 leader 分區,但是沒有同步給 follower 就宕機了
這個問題也好解決:生產者可以在發送消息前,先將消息持久化。至多是用了存儲空間,現在磁盤空間可以說是最不值錢的了,而且我們還可以定期進行歸檔壓縮/刪除處理,問題不大。
– 消費者消費消息遇到消息丟失或者消息重復處理
  • 消息丟失
消息丟失一般是以下這幾種情況:
  1. 消費者拿到消息了,但是處理過程中發生異常
  2. 消費者提交消費位移的設計不合理
針對這個問題,我們通常拿到消息會選擇將消息持久化在本地,然后再做消息處理,處理出問題也可以重復處理。這種設計滿足我們大多數場景,但是對于消息生產速度遠高于我們持久化速度的場景可能就不適用了,因為我們要考慮消息堆積問題。不管是這個問題,還是有些場景下無法找生產者重新投遞消息的問題,都讓我們期待著消息中間件可以支持消息回溯功能。
  • 重復消費
這個可以交由使用者自己做冪等處理
– 消息需要有序消費
我們知道 Kafka 是分區內消息有序的。當然,需要有序的消息就只能使用一個分區,無疑是以 Kafka 的水平擴展能力作為代價的。如果是需要全局有序,而我們又確定使用 Kafka,而且單分區的吞吐量不能滿足要求,那么我們只能自己進行額外設計來保證了。

2.1 acks配置對消息丟失的影響

2.1.1 acks=1

消息成功寫入 leader 后,就會告訴生產者投遞成功。
帶你吃透Kafka的可靠性設計
如上圖例子,一共三個分區,其中 follower1 和 follower2 均屬于 ISR。假設 leader 成功寫入 3 和 4 之后,ISR 還沒同步,leader 就宕機了,這樣就丟失了 3 和 4,如下圖:
帶你吃透Kafka的可靠性設計

2.1.2 acks=-1 或者 acks=all

消息不僅要成功寫入 leader,還要 ISR 中的所有 follower 同步完成后,才會告知生產者投遞成功。
還是 2.1.1 的例子,這里無非會有兩種情況:
  • leader 在同步完成后宕機
帶你吃透Kafka的可靠性設計
  • leader 在同步完成前宕機
帶你吃透Kafka的可靠性設計
這個配置對 Kafka 的性能會有較大影響,需要自己斟酌得失。

2.2 unclean.leader.election.enable

這個配置是用來控制 Kafka 是否可以選舉非 ISR 中的副本為 leader,0.11.0.0 之后的版本默認為 false。雖然設置為 true 可以提高 Kafka 的可用性,但是會降低 Kafka 數據的可靠性。

2.3 小結

上面提出的問題均有指出和 Kafka 相關部分的設計是哪些,這里再總結一下:
  • 如何避免腦裂問題——了解 Kafka 的 leader 選舉機制
  • 數據同步&數據一致性問題——了解 Kafka 的多副本設計
  • 消息順序消費問題——了解 Kafka 的日志同步機制(分區有序)

3.副本設計

副本( Replica )是分布式系統中常見的概念之一,指的是分布式系統對數據和服務提供的一種冗余方式。
我們知道 Kafka 通過多副本機制,增強了容災備份的能力,并且實現了故障轉移。這無疑是大大提高了 Kafka 的可用性,下面筆者會帶著大家一起看 Kafka 的副本機制是如何設計的。
在此之前,先簡單復習幾個相關的概念:
  • 副本是相對分區而言的,即副本是指某個分區的副本
  • 在多副本情況下,其中一個副本為 leader,其它均為 follower。只有 leader 對外提供服務,follower 僅同步leader 數據
  • 分區中所有的副本集合稱為 AR,ISR 是與 leader 保持同步狀態的副本集合,leader 也是 ISR 中的一員
  • LEO 是每個分區下一條消息要寫入的位置
  • HW 是 ISR 中最小的 LEO,消費者只能拉取 HW 之前的消息

3.1 失效副本

正常情況下,分區中所有副本都應該屬于 ISR,但是網絡具有不可靠性。因此,難免在某一個時刻會有一些成員會被踢出 ISR,這些副本要么處于同步失效狀態,要么功能失效,這些副本統稱為失效副本。
功能失效指的是無法工作,比如某個 broker 宕機了,那么在它上面的分區就會失效。
同步失效又是怎么判斷是否同步失效的呢?是通過參數 replica.lag.time.max.ms 來判斷的,默認是 10000 毫秒。當某個 follower 同步滯后 leader 的時間超過 10 秒,則判定為同步失效。
具體實現原理如下:
帶你吃透Kafka的可靠性設計
當 follower 將 leader LEO 之前的消息全部同步完成,那么會認為該 follower 已經追上 leader,并更新 lastCaughtUpTimeMs。Kafka 的副本管理器有一個副本過期檢測的定時任務,如果發現當前時間 - lastCaughtUpTimeMs > 10秒,則判定同步失效。
除了時間設置以外,還有另一個參數 replica.lag.max.message(默認4000,這個是 broker 級別的參數),也是用來判定失效副本的。
一般情況下,這兩個參數都是使用默認值就可以,因為如果沒有調優經驗,自己亂配置,容易導致 ISR 變動過于頻繁。同時,需要監控失效副本的數量,因為它是衡量 Kafka 是否健康的一個很重要的指標。
PS:新加入的副本因子/宕機恢復后重新加入的副本在追趕上 leader 之前,也會一直處于失效狀態。

3.1.1 失效副本的作用

失效副本為 Kafka 帶來了什么收益呢?為什么需要設計這么一個狀態呢?
大家不妨試想下:假設允許 ISR 中有一個副本同步一直跟不上 leader。當 leader 發生宕機時,這個 follower 被選舉成了新的 leader,那么這時就會發生消息丟失。
一般會造成副本失效基本是以下兩個原因:
  • follower 副本進程卡頓,在一段時間內無法發起同步請求,比如說頻繁發生 FULL GC
  • follower 同步過慢,在一段時間內無法追上 leader,比如 I/O有問題(筆者實際工作中遇到過一次,公司搭建自己的物理機房,用了二手服務器,有一臺服務器I/O老化導致讀寫數據慢,導致了副本失效,消息堆積等問題)

3.2 LEO 與 HW

這一小節會更進一步去講解它們之間的關系,讓大家可以更清楚 Kafka 的副本同步機制。
假設現在有 3 個 broker,某個 topic 有 1 個分區,3 個副本。現在有一個 producer 發送了一條消息,這 3 個副本會發生些什么操作。
帶你吃透Kafka的可靠性設計
具體步驟如下:
  1. producer 發送消息到 leader
  2. leader 將消息追加到日志,并且更新日志的偏移量
  3. follower 執行定時任務向 leader 發送 fetch request 同步數據,該請求會帶上自己的 LEO
  4. leader 讀取本地日志,并更新 follower 的信息
  5. leader 返回 fetch response 給 follower,response 會包含 HW
  6. follower 將消息追加到本地日志,并更新日志的偏移量
為了更直觀地理解上面的步驟,下面將會用圖來展示。
1.一個新建的 topic 被寫入了 5 條消息,兩個 follower 去拉取數據
帶你吃透Kafka的可靠性設計
2.leader 給 follower 返回 fetch response,并且 leader 又被寫入了 5 條消息
帶你吃透Kafka的可靠性設計
 其中 follower1 同步了 2 條數據,而 follower2 同步了 3 條數據。
 而 follower 的 HW = min(自己的LEO, 同步回來的HW)
3.follower 再次同步數據,同時 leader 又被寫入了 5 條消息
帶你吃透Kafka的可靠性設計
 leader 更新了 HW
4.leader 給 follower 返回 fetch response
帶你吃透Kafka的可靠性設計
 根據公式,follower 更新 HW = 3
在一個分區中,leader 所在 broker 會記錄所有副本的 LEO 和 自己的 HW;而 follower 所在的 broker 只會記錄自己的 LEO 和 HW。因此,在邏輯層面上,我們可以得到下圖:
帶你吃透Kafka的可靠性設計
0.11.0.0版本之前,Kafka 是基于 HW 的同步機制,但是這個設計有可能出現數據丟失和數據不一致的問題。Kafka 后面的版本通過 leader epoch 來進行優化。

3.3 數據丟失 & 數據不一致的解決方案

3.2小節說到了 LEO 與 HW 的更新機制,并且提到這種設計可能會出現數據丟失和數據不一致。我們先一起來看下這兩個問題是如何產生的。

3.3.1 數據丟失

假設某一分區在某一時刻的狀態如下圖(L 代表是 leader):
帶你吃透Kafka的可靠性設計
可以看見副本A的 LEO 是 2,HW 是 1;副本B的 LEO 是 2,HW 是 2。顯然,哪怕沒有新的消息寫入副本B中,副本A也要過一小段時間才能追上副本A,并更新 HW。
假設在副本A更新 HW = 2之前,A宕機了,隨后立馬就恢復。這里會有一個截斷機制——根據宕機之前持久化的HW 恢復消息。也就是說,A只恢復了 m1,m2 丟失了。
再假設 A 剛恢復,B 也宕機了,A 成為了 leader。這時 B 又恢復了,并成為了 follower。由于 follower 的 HW 不能比 leader 的 HW 高,所以 B 的 m2 也丟失了。
帶你吃透Kafka的可靠性設計
總結:這里大家可以發現 follower 的 HW 更新是有一定間隙的,像我這個例子其實 follower 是拿到 m2 了,只不過 HW 要追上 leader 需要等下一次的 fetch request。除非配置 acks=-1 并且配置min.insync.replicas 大于 1,unclean.leader.election.enable = true 才行。

3.3.2 數據不一致

帶你吃透Kafka的可靠性設計
假設某一分區在某一時刻,副本A 的 HW = 2,LEO = 2;副本B 的 HW = 1,LEO = 1。
又假設它們同時掛了,B 先恢復。這時,B 會成為 leader,如下圖:
帶你吃透Kafka的可靠性設計
此時,B 寫入新消息 m3,并將 HW、LEO 更新為 2。此時,A 也恢復了。由于 A 的 HW 也是 2,所以沒有截斷消息。如下圖:
帶你吃透Kafka的可靠性設計
這樣一來,A 中 offset = 1 的消息是 m2,B 中 offset = 1 的消息是 m3,數據不一致了。

3.3.3 leader epoch

為了解決 3.3.1 和 3.3.2 的問題,Kafka 從 0.11.0.0 開始引入 leader epoch,在需要截斷時使用 leader epoch 作為依據,而不再是 HW。
如果看框架代碼比較多的同學應該知道 epoch 是相當于版本的這么一個概念。leader epoch 的初始值是 0,每變更一次 leader,leader epoch 就會增加 1。另外,每個副本中還會增加一個矢量<LeaderEpoch => StartOffset>,其中 StartOffset 是當前 leader epoch 下寫入第一條消息的偏移量。每個副本的 Log 下都有一個 leader-epoch-checkpoint 文件,在發生 leader 變更時,會將對應的矢量追加到這個文件中。

3.3.3.1 解決數據丟失問題

帶你吃透Kafka的可靠性設計
還是3.3.1的例子,只不過多了 leader epoch 矢量信息。
副本A:HW=1,LEO=2,LE(leader epoch)=0,Offset(StartOffset)=0
leader-副本B:HW=2,LEO=2,LE=0,Offset(StartOffset)=0
假設在副本A更新 HW = 2之前,A宕機了,隨后立馬就恢復。不過這里不會立馬進行截斷日志操作,而是會發送一個 OffsetsForLeaderEpochRequest 請求給 B,B 作為目前的 leader 在收到請求之后會返回 OffsetsForLeaderEpochResponse 給 A。
我們先來看下 OffsetsForLeaderEpochRequest 和 OffsetsForLeaderEpochResponse 的數據結構。如下圖:
  • OffsetsForLeaderEpochRequest
帶你吃透Kafka的可靠性設計
 A 會將自己的 leader epoch 信息給 leader(A的 leader epoch 這里簡化成 LE_A)。這里會出現兩種情況:
– 變更了 leader
 B 會返回 LE_A+1 的 StartOffset 給 A
– 沒有變更 leader
 B 會返回 A 的 LEO 給 A
 因此,我們可以把 OffsetsForLeaderEpochRequest 看作是一個查詢 follower 當前 leader_epoch 的 LEO。
  • OffsetsForLeaderEpochResponse
帶你吃透Kafka的可靠性設計
這個例子中,B 會返回2給 A,而此時的 A 的 LEO 剛好是 2,所以不用進行截斷日志。如下圖:
帶你吃透Kafka的可靠性設計
如果此時B掛了,A成了 leader,并有 m3 寫入,就會得到下圖:
帶你吃透Kafka的可靠性設計
可以看見 m2 并沒有丟失,并且也更新了 leader_epoch 矢量為 (1,2)。

3.3.3.2 解決數據不一致問題

帶你吃透Kafka的可靠性設計
上圖是3.3.2的例子。副本A是 leader,B 是 follower。
A 的 HW=2,LEO=2,LE=(0,0)
B 的 HW=1,LEO=1,LE=(0,0)
此時,A 和 B 同時宕機,并且 B 先恢復成為了 leader。此時,epoch 變成了 1。另外,新消息 m3 成功寫入,就會得到下圖:
帶你吃透Kafka的可靠性設計
接著,A 也恢復了,這時 A 不會急著截斷日志,而是給 leader 發送 OffsetsForLeaderEpochRequest,B 會返回 LEO = 1 給 A。因此,A 會截斷日志,刪除 m2。之后,再給 B 發送 fetch request,得到 B 的響應并更新后,將得到下圖:
帶你吃透Kafka的可靠性設計
這樣數據不一致問題就解決了。
這里大家可能會有疑問,m2不是丟失了嗎?是的,這種設計因為更新具有一定的間隙,并且沒有事務管理,所以會有丟失消息的風險。
從 CAP 定理來看,這里的設計屬于 AP。為什么這么說呢?大家不妨想一下,如果為了不丟失數據,這里加了事務控制的設計,那么對于分區而言它的吞吐量是會下降的,甚至是不可用的,因為響應速度是由短板的副本所決定的。對于定位是高吞吐量的 Kafka 而言,這顯然是不可接受的。

3.4 小結

Kafka 通過多副本機制增強了容災備份的能力,并且基于多副本機制實現了故障轉移,避免了單點問題,但同時也引進了新的問題——數據丟失和數據不一致。從 0.11.0.0 版本開始,Kafka 增加了 leader epoch,它對這兩個問題進行了優化。雖然無法完全避免消息丟失,但是從實際的使用角度而言,這個問題其實并不大。有實際工作經驗的同學應該都知道,我們發送消息難以避免需要重推,哪怕消息中間件做到了百分百不丟失,其實我們在使用時仍然會做防止消息丟失的設計。相對而言,數據一致性就更重要了,否則很容易讓訂閱消息的下游系統出現臟數據。

4 leader 選舉機制

在 Kafka 集群中會有一個或者多個 broker,其中有一個 broker 會被選舉為控制器,它負責管理整個集群中所有分區和副本的狀態。分區的 leader 出現故障時,由控制器負責為其選舉新的 leader;當某個分區的 ISR 發生變化時,由控制器負責通知所有 broker 更新其元數據信息;當某個 topic 的分區數量發生變化時,還是由控制器負責分區的重新分配。因此,只要控制器正常工作,分區的 leader 就是唯一的,不會有腦裂問題。
那么, Kafka 是如何保證控制器只有一個的呢?如果控制器發生異常了怎么辦?控制器的選舉和異常恢復又是怎樣的?

4.1 控制器

控制器是 broker 維度的角色,它負責管理整個集群中所有分區和副本的狀態。
Kafka 中的控制器選舉工作依賴于 ZooKeeper,成功競選為控制器的 broker 會在 ZooKeeper 中創建 /controller 臨時節點,節點會存儲以下信息:
{
 "version ": 1,
 "brokerid": 0,
 "timestamp": "1529210278988"
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
 

分享到:
標簽:Kafka
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定