kafka問題

1. Kafka是如何保障數據不丟失的?

kafka如何保障數據不丟失,也就是kafka提供了什麼機制或者架構來保障數據的可靠性。java

  • 分區副本架構
  • 數據複製同步

主要從如下三個方面概述markdown

1.Topic 副本因子個數:replication.factor >= 3
2.同步副本列表(ISR):min.insync.replicas = 2
3.禁用unclean選舉: unclean.leader.election.enable=false
複製代碼

1. 副本機制

  1. kafka的topic能夠分爲多個副本,該配置能夠經過replication.factor實現。
  2. 副本類型能夠分爲領導者副本(leader )和追隨者副本,每一個分區在建立的時候,都會選舉一個副本成爲領導者副本,其它的默認成爲跟隨者副本。(依賴於zookeeper實現
  3. 只有leader 副本纔會提供對外的服務,follower 副本是不會處理任務服務請求的,只是作數據同步,數據備份。
  4. 爲了提升數據的可用性,副本通常會分佈在不一樣的broker中,通常也建議把broker配置在不一樣的機架上,提升可用性。

2. ISR(In-sync replica):同步副本列表

  1. leader副本和與leader副本保持同步的follower副本均在ISR中。
  2. replica.lag.time.max.ms這是配置follower副本與leader副本同步的最長時間,若是在該時間內follower副本沒有與leader副本同步,則會將該follower踢出ISR。
  3. 爲了提升kafka的可靠性,咱們通常須要將最小同步副本數量設置大一點,對於一個包含3 個副本的主題分區,若是min.insync.replicas=2 ,那麼至少要存在兩個同步副本才能向分區寫入數據。

注意: 若是進行了上面的配置,此時必需要保證ISR中至少存在兩個副本,若是ISR中的副本個數小於2,那麼Broker就會中止接受生產者的請求。嘗試發送數據的生產者會收到NotEnoughReplicasException異常,消費者仍然能夠繼續讀取已有的數據。session

3. 禁用unclean選舉

  1. 選擇一個同步副本列表中的分區做爲leader 分區的過程稱爲clean leader election
  2. 非同步副本中選取一個副本做爲leader的過程叫作unclean leader election
  • 開啓unclean leader election這種方式進行選舉leader,能夠經過配置unclean.leader.election.enable進行設置。
  1. 開啓的優勢缺點:
  • 背景:由於ISR是動態的,因此存在ISR列表中爲空的狀況,在leader掛了,其它follower沒有同步時,將會產生這種狀況,而一旦發生這種狀況,整個kafka將不能提供服務了。
  • 高可用-開啓(好比實時點擊流分析系統):爲了kafka集羣可以一直提供服務(優勢),能夠開啓unlean.leader選舉,可是由於選舉的是非ISR列表中的follower做爲新的leader,由於這些follower上的信息可能與以前的leader上的數據相差比較大,那麼新選舉的follower成爲leader後,由於沒有同步老leader上的數據,就會產生數據丟失的狀況(缺點)
  • 數據一致性-禁用unclean選舉(應用:好比銀行,要去數據一致性高):禁用的話,那麼選舉leader只能從ISR中選舉,這樣能夠能夠保障數據的一致性(固然,這個一致性不能徹底保障,由於follower中的數據是異步和leader同步的,若是數據沒有同步完,leader就掛了,那麼新選舉的leader裏面由於沒有徹底同步老leader數據,就會存在數據部分丟失的可能性。除非設置裏acks=all,確保了全部follower所有同步了leader,並響應給producer
follower和leader數據同步和以下兩個參數關係密切:

replica.lag.time.max.ms:同步副本滯後與leader副本的時間
zookeeper.session.timeout.ms:與zookeeper會話超時時間
複製代碼

2. 如何解決kafka數據丟失問題?

  • acks=all:全部副本同步後
  • 配置 retries > 0 的 Producer 可以自動重試消息發送,避免消息丟失。
  • 配置auto.offset.reset,這個參數有兩種配置。一種是earliest:消費者會從分區的開始位置讀取數據,無論偏移量是否有效,這樣會致使消費者讀取大量的重複數據,但能夠保證最少的數據丟失。一種是latest(默認),若是選擇了這種配置, 消費者會從分區的末尾開始讀取數據,這樣能夠減小重複處理消息,但頗有可能會錯過一些消息。

補充讓kafka數據不丟失

  • 不要使用 producer.send(msg),而要使用 producer.send(msg, callback)。
  • 設置 acks = all (確保全部follower都同步數據完成在響應producer)
  • 設置 retries 爲一個較大的值。(當producer發送消息失敗,多嘗試從新發送消息)
  • 設置 unclean.leader.election.enable = false。(禁用非同步follower參與競選leader)
  • 設置 replication.factor >= 3。(配置分區副本數大於等於3)
  • 設置 min.insync.replicas > 1。(配置可用ISP同步副本數大於1)
  • 確保 replication.factor > min.insync.replicas。(分區副本數大於能夠同步副本數配置)

這個和上面的推斷結果差很少。架構

3. kafka能夠保障永久不丟失數據嗎?

Kafka 只對「已提交」的消息(committed message)作有限度的持久化保證負載均衡

    1. 已提交:就是數據已經記錄在log文件中的數據,kafka響應給producer,數據已經接收成功的數據(acks=1,或者acks=all)
    1. 這些消息的日誌文件所在的broker是正常的
  • 因此總而言之,kafka是能夠作到保障永久不丟失數據的,只不過要有條件限制

4. 如何保障kafka中的消息是有序的?

  1. kafka是分區有序的,若是一個主題有多個分區,那麼Kafka會按照key將其發送到對應的分區中,因此,對於給定的key,與其對應的record在分區內是有序的。

方案一: 對於須要保障消息有序的topic,設置單個分區,可是會影響吞吐量。異步

方案二: 設置兩個參數:post

  • 消息發送失敗是,重試次數,配置retries>0,還須要配置max.in.flight.requests.per.connections:1,該參數是保障消息寫入的順序,當嘗試重發第一批消息的時候,就不會有其餘消息嘗試發送給broker。這種也會影響吞吐量,可是能夠保障消息是順序發送的。

5. 如何肯定kafka分區的數據量?

一個簡單的計算公式爲:分區數 = max(生產者數量,消費者數量)spa

生產者數量=總體生產吞吐量/每一個生產者對單個分區的最大生產吞吐量日誌

消費者數量=總體消費吞吐量/每一個消費者從單個分區消費的最大吞吐量code

選擇合適的分區數量能夠達到高度並行讀寫和負載均衡的目的,在分區上達到均衡負載是實現吞吐量的關鍵。須要根據每一個分區的生產者和消費者的指望吞吐量進行估計。

6. 從新平衡kafka集羣?

在下面狀況發生時,須要重平衡集羣:

  • 主題分區在整個集羣裏的不均衡分佈形成了集羣負載的不均衡。
  • broker離線形成分區不一樣步。
  • 新加入的broker 須要從集羣裏得到負載。

使用kafka-reassign-partitions.sh命令進行重平衡

7. 如何查看消費組是否存在滯後消費?

備註:

參考以下

  1. kafka-問題
  2. java小咖秀
相關文章
相關標籤/搜索