Kafka有兩個很重要的配置參數,acks
與min.insync.replicas
.其中acks
是producer的配置參數,min.insync.replicas
是Broker端的配置參數,這兩個參數對於生產者不丟失數據起到了很大的做用.接下來,本文會以圖示的方式講解這兩個參數的含義和使用方式。經過本文,你能夠了解到:html
✍Kafka的分區副本程序員
✍什麼是同步副本(In-sync replicas)安全
✍什麼是acks確認機制服務器
✍什麼是最小同步副本網絡
✍ack=all與最小同步副本是如何發揮做用的架構
Kafka的topic是能夠分區的,而且能夠爲分區配置多個副本,改配置能夠經過replication.factor
參數實現. Kafka中的分區副本包括兩種類型:領導者副本(Leader Replica)和追隨者副本(Follower Replica),每一個分區在建立時都要選舉一個副本做爲領導者副本,其他的副本自動變爲追隨者副本. 在 Kafka 中,追隨者副本是不對外提供服務的,也就是說,任何一個追隨者副本都不能響應消費者和生產者的讀寫請求. 全部的請求都必須由領導者副原本處理. 換句話說,全部的讀寫請求都必須發往領導者副本所在的 Broker,由該 Broker 負責處理. 追隨者副本不處理客戶端請求,它惟一的任務就是從領導者副本異步拉取消息,並寫入到本身的提交日誌中,從而實現與領導者副本的同步.異步
Kafka默認的副本因子是3,即每一個分區只有1個leader副本和2個follower副本.具體以下圖所示:分佈式
上面提到生產者客戶端僅寫入Leader broker,跟隨者異步複製數據。因爲Kafka是一個分佈式系統,必然會存在與 Leader 不能實時同步的風險,因此須要一種方法來判斷這些追隨者是否跟上了領導者的步伐, 即追隨者是否同步了最新的數據.換句話說,Kafka 要明確地告訴咱們,追隨者副本到底在什麼條件下才算與 Leader 同步?這就是下面所要說的ISR同步副本機制.ide
In-sync replica(ISR)稱之爲同步副本,ISR中的副本都是與Leader進行同步的副本,因此不在該列表的follower會被認爲與Leader是不一樣步的. 那麼,ISR中存在是什麼副本呢?首先能夠明確的是:Leader副本老是存在於ISR中. 而follower副本是否在ISR中,取決於該follower副本是否與Leader副本保持了「同步」.微服務
尖叫提示:對於"follower副本是否與Leader副本保持了同步"的理解以下:
(1)上面所說的同步不是指徹底的同步,即並非說一旦follower副本同步滯後與Leader副本,就會被踢出ISR列表.
(2)Kafka的broker端有一個參數
replica.lag.time.max.ms
, 該參數表示follower副本滯後與Leader副本的最長時間間隔,默認是10秒. 這就意味着,只要follower副本落後於leader副本的時間間隔不超過10秒,就能夠認爲該follower副本與leader副本是同步的,因此哪怕當前follower副本落後於Leader副本幾條消息,只要在10秒以內遇上Leader副本,就不會被踢出出局.(3)若是follower副本被踢出ISR列表,等到該副本追上了Leader副本的進度,該副本會被再次加入到ISR列表中,因此ISR是一個動態列表,並非靜態不變的。
如上圖所示:Broker3上的partition1副本超過了規定時間,未與Leader副本同步,因此被踢出ISR列表,此時的ISR爲[1,3].
acks參數指定了必需要有多少個分區副本收到消息,生產者才認爲該消息是寫入成功的,這個參數對於消息是否丟失起着重要做用,該參數的配置具體以下:
acks=0,表示生產者在成功寫入消息以前不會等待任何來自服務器的響應. 換句話說,一旦出現了問題致使服務器沒有收到消息,那麼生產者就無從得知,消息也就丟失了. 改配置因爲不須要等到服務器的響應,因此能夠以網絡支持的最大速度發送消息,從而達到很高的吞吐量。
acks=1,表示只要集羣的leader分區副本接收到了消息,就會向生產者發送一個成功響應的ack,此時生產者接收到ack以後就能夠認爲該消息是寫入成功的. 一旦消息沒法寫入leader分區副本(好比網絡緣由、leader節點崩潰),生產者會收到一個錯誤響應,當生產者接收到該錯誤響應以後,爲了不數據丟失,會從新發送數據.這種方式的吞吐量取決於使用的是異步發送仍是同步發送.
尖叫提示:若是生產者收到了錯誤響應,即使是從新發消息,仍是會有可能出現丟數據的現象. 好比,若是一個沒有收到消息的節點成爲了新的Leader,消息就會丟失.
acks =all,表示只有全部參與複製的節點(ISR列表的副本)所有收到消息時,生產者纔會接收到來自服務器的響應. 這種模式是最高級別的,也是最安全的,能夠確保不止一個Broker接收到了消息. 該模式的延遲會很高.
上面提到,當acks=all時,須要全部的副本都同步了纔會發送成功響應到生產者. 其實這裏面存在一個問題:若是Leader副本是惟一的同步副本時會發生什麼呢?此時至關於acks=1.因此是不安全的.
Kafka的Broker端提供了一個參數min.insync.replicas
,該參數控制的是消息至少被寫入到多少個副本纔算是"真正寫入",該值默認值爲1,生產環境設定爲一個大於1的值能夠提高消息的持久性. 由於若是同步副本的數量低於該配置值,則生產者會收到錯誤響應,從而確保消息不丟失.
以下圖,當min.insync.replicas=2且acks=all時,若是此時ISR列表只有[1,2],3被踢出ISR列表,只須要保證兩個副本同步了,生產者就會收到成功響應.
以下圖,當min.insync.replicas=2,若是此時ISR列表只有[1],2和3被踢出ISR列表,那麼當acks=all時,則不能成功寫入數;當acks=0或者acks=1能夠成功寫入數據.
這種狀況是很容易引發誤解的,若是acks=all且min.insync.replicas=2,此時ISR列表爲[1,2,3],那麼仍是會等到全部的同步副本都同步了消息,纔會向生產者發送成功響應的ack.由於min.insync.replicas=2只是一個最低限制,即同步副本少於該配置值,則會拋異常,而acks=all,是須要保證全部的ISR列表的副本都同步了才能夠發送成功響應. 以下圖所示:
acks=0,生產者在成功寫入消息以前不會等待任何來自服務器的響應.
acks=1,只要集羣的leader分區副本接收到了消息,就會向生產者發送一個成功響應的ack.
acks=all,表示只有全部參與複製的節點(ISR列表的副本)所有收到消息時,生產者纔會接收到來自服務器的響應,此時若是ISR同步副本的個數小於min.insync.replicas
的值,消息不會被寫入.
熱門內容: