Kafka超詳細生產者詳解

分區策略

分區的原因

  1. 方便在集羣中擴展,每個Partition可以通過調整以適應它所在的機器,而一個topic又可以有多個Partition組成,因此整個集羣就可以適應任意大小的數據了;
  2. 可以提高併發,因爲可以以Partition爲單位讀寫了。

分區的原則

我們需要將producer發送的數據封裝成一個ProducerRecord對象。
image.png

  1. 指明 partition 的情況下,直接將指明的值直接作爲 partiton 值;
  2. 沒有指明 partition 值但有 key 的情況下,將 key 的 hash 值與 topic 的 partition 數進行取餘得到 partition 值;
  3. 既沒有 partition 值又沒有 key 值的情況下,第一次調用時隨機生成一個整數(後面每次調用在這個整數上自增),將這個值與 topic 可用的 partition 總數取餘得到 partition 值,也就是常說的 round-robin 算法。

數據可靠性保證

爲保證producer發送的數據,能可靠的發送到指定的topic,topic的每個partition收到producer發送的數據後,都需要向producer發送ack(acknowledgement確認收到),如果producer收到ack,就會進行下一輪的發送,否則重新發送數據
image.png

副本數據同步策略

方案 優點 缺點
半數以上完成同步,就發送ack 延遲低 選舉新的leader時,容忍n臺節點的故障,需要2n+1個副本
全部完成同步,才發送ack 選舉新的leader時,容忍n臺節點的故障,需要n+1個副本 延遲高

Kafka選擇了第二種方案,原因如下:

  1. 同樣爲了容忍n臺節點的故障,第一種方案需要2n+1個副本,而第二種方案只需要n+1個副本,而Kafka的每個分區都有大量的數據,第一種方案會造成大量數據的冗餘。
  2. 雖然第二種方案的網絡延遲會比較高,但網絡延遲對Kafka的影響較小。

ISR

採用第二種方案之後,設想以下情景:leader收到數據,所有follower都開始同步數據,但有一個follower,因爲某種故障,遲遲不能與leader進行同步,那leader就要一直等下去,直到它完成同步,才能發送ack。這個問題怎麼解決呢?
Leader維護了一個動態的in-sync replica set (ISR),意爲和leader保持同步的follower集合。當ISR中的follower完成數據的同步之後,leader就會給follower發送ack。如果follower長時間未向leader同步數據,則該follower將被踢出ISR,該時間閾值由replica.lag.time.max.ms參數設定。Leader發生故障之後,就會從ISR中選舉新的leader。

ack應答機制

對於某些不太重要的數據,對數據的可靠性要求不是很高,能夠容忍數據的少量丟失,所以沒必要等ISR中的follower全部接收成功。
所以Kafka爲用戶提供了三種可靠性級別,用戶根據對可靠性和延遲的要求進行權衡,選擇以下的配置。
acks參數配置:
acks:

  1. producer不等待broker的ack,這一操作提供了一個最低的延遲,broker一接收到還沒有寫入磁盤就已經返回,當broker故障時有可能丟失數據;
  2. producer等待broker的ack,partition的leader落盤成功後返回ack,如果在follower同步成功之前leader故障,那麼將會丟失數據;
    image.png
    -1(all):producer等待broker的ack,partition的leader和follower全部落盤成功後才返回ack。但是如果在follower同步完成後,broker發送ack之前,leader發生故障,那麼會造成數據重複。
    image.png

故障處理細節

image.png

  1. follower故障
    follower發生故障後會被臨時踢出ISR,待該follower恢復後,follower會讀取本地磁盤記錄的上次的HW,並將log文件高於HW的部分截取掉,從HW開始向leader進行同步。等該follower的LEO大於等於該Partition的HW,即follower追上leader之後,就可以重新加入ISR了。
  2. leader故障
    leader發生故障之後,會從ISR中選出一個新的leader,之後,爲保證多個副本之間的數據一致性,其餘的follower會先將各自的log文件高於HW的部分截掉,然後從新的leader同步數據。
    注意:這隻能保證副本之間的數據一致性,並不能保證數據不丟失或者不重複。

Exactly Once語義

對於某些比較重要的消息,我們需要保證exactly once語義,即保證每條消息被髮送且僅被髮送一次。
在0.11版本之後,Kafka引入了冪等性機制(idempotent),配合acks = -1時的at least once語義,實現了producer到broker的exactly once語義。
idempotent + at least once = exactly once
使用時,只需將enable.idempotence屬性設置爲true,kafka自動將acks屬性設爲-1。
關注微信公衆號
簡書:https://www.jianshu.com/u/0278602aea1d
CSDN:https://blog.csdn.net/u012387141

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章