kafka筆記6

咱們討論可靠性時,通常使用保證這個詞,它是確保系統在各類不一樣的環境下可以發生一致的行爲。Kafka能夠在哪些方面做出保證呢?數據庫

1.Kafka能夠保證分區消息的順序apache

2.只有消息被寫入分區的全部同步副本時,它纔會被認爲是已提交的。生產者能夠選擇接收不一樣類型的確認。服務器

3.只要還有一個副本是活躍的,那麼提交的消息就不會丟失。網絡

4.消費者只能讀取已經提交的消息。架構

Kafka的管理員和開發者能夠在配置參數上做出權衡,從而獲得它們想要的可靠性,這種權衡通常是指消息存儲的可靠性和一致性的重要程度與可用性,高吞吐量,低延遲和硬件成本的重要程度之間的權衡。框架

6.2複製異步

Kafka的複製機制和分區的多副本架構師Kafka可靠性保證的核心。把消息寫入多個副本可以使Kafka在發生崩潰時仍能保證消息的持久性。工具

Kafka的主題被分爲多個分區,分區是基本的數據塊,分區存儲在單個磁盤上,Kafka能夠保證分區裏的事件是有序的,分區能夠在線(可用),也能夠離線(不可用)。每一個分區能夠有多個副本,其中一個副本是首領,全部的事件都直接發送給首領副本,或者從首領副本讀取事件。其它副本只須要與首領保持同步,並及時複製最新的事件,當首領副本不可用時,其中一個副本會成爲新的首領。性能

分區首領時同步副本,對於跟蹤者副原本說,它須要知足如下條件才能被認爲是同步的。測試

1.與zookeeper之間有一個活躍的會話,(過去6秒(可配置)向zookeeper發送過心跳)。

2.在過去10秒(可配置)從首領獲取過消息。

3.過去10秒獲取過最新的消息,光從首領獲取消息是不夠的,還必須是幾乎零延遲的。

若是不能知足以上任何一點,那麼就被認爲是不一樣步的。

一個滯後的同步副本會致使生產者和消費者變慢,由於在消息被認爲已提交以前,客戶端會等待全部同步副本接收消息。

6.3broker配置

broker有三個配置參數會影響Kafka的消息存儲的可靠性。與其它配置參數同樣,它們能夠應用在broker級別,用於控制全部主題的行爲,也能夠應用在主題級別,用於控制特定主題的行爲。

在主題級別控制可靠性,意味着Kafka集羣能夠同時擁有可靠的主題和非可靠的主題。

6.3.1複製係數

主題級別的配置參數是replication.factor,而在broker級別能夠經過default.repllication.factor來配置自動建立的主題。

咱們假定主題的複製係數是3,也就是說每一個分區總共會被3個不一樣的broker複製三次。即便在主題建立以後,也能夠經過新增或移除副原本改變複製係數。

更高的複製係數會帶來更好的可用性,可靠性和更少的故障。

副本的分佈也很重要,默認狀況下,Kafka會確保分區的每一個副本都被放在不一樣的broker上,若是這些broker處在同一個機架上,一旦機架的交換機發生故障,分區就會不可用,因此咱們建議把broker分佈在多個不一樣的機架上。並使用broker.reck參數來爲每一個broker配置所在機架的名字。若是配置了機架名字,Kafka會保證分區的副本被分佈在多個機架上,從而得到更高的可用性。

若是首領不可用時,其它副本都是不一樣步的,若是把unclean.leader.election.enable設爲true,就是容許不一樣步的副本稱爲首領,那麼咱們將面臨丟失消息的風險。若是把這個參數設爲false,就要等待原先的首領從新上線,從而下降了可用性。銀行系統通常會禁用這種不徹底的首領選舉(把這個參數設爲false)。

6.3.3最少同步副本

min.insync.replicas

根據Kafka對可靠性保證的定義,消息只有在被寫入到全部同步副本以後纔會被認爲是已提交的。若是兩個副本都變爲不可用,那麼broker都會中止接受生產者的請求。嘗試發送數據的生產者就會收到NoEnoughReplicasException異常。但消費者仍然能夠繼續讀取已有的數據。

6.4在可靠的系統裏使用生產者

每一個使用Kafka的開發人員必須注意兩件事:

1.根據可靠性需求配置恰當的acks值

2.在參數配置和代碼里正確處理錯誤。

6.4.1發送確認

生產者能夠選擇如下三種確認模式。

acks=0意味着若是生產者經過網絡把消息發送出去,就認爲消息已經成功寫入Kafka,這種狀況下有可能發生錯誤。可是速度是最快的。

acks=1意味着首領在收到消息並把它寫入到分區數據文件就會返回確認信息,這個狀況下,若是發生正常的首領選舉,生產者會收到異常,若是生產者能恰當處理異常,選擇重發,最終消息仍然能夠發送成功,但這個模式仍然可能發生丟失數據,好比消息成功寫入首領,在複製到跟隨者副本以前,首領發生崩潰。

acks=all,意味着首領在返回確認以前,會等待全部同步副本收到消息。若是和min.insync.replicas參數結合起來,就能夠決定在返回確認前至少有多少副本可以收到消息。這是最保險的作法——生產者會一直重試直到消息被成功提交。不過生產者在繼續發送其它消息以前須要等待全部的副本都收到當前消息。雖然能夠經過使用異步模式和更大的批次加快速度,但這樣一般會下降吞吐量。

6.4.2配置生產者的重試參數

生產者須要處理的錯誤包含兩部分:一部分是生產者能夠自動處理的錯誤,還有一部分是須要開發者手動處理的錯誤。

若是broker返回的錯誤能夠經過重試來解決,那麼生產者會自動處理這些錯誤。生產者向broker發送消息,broker能夠返回一個成功響應碼或者一個錯誤響應碼。錯誤響應碼能夠分爲兩種:

一種是重試以後能夠解決的,還有一種是沒法經過重試解決的。

通常狀況下,若是目標是不丟失任何消息,那麼最好在生產者遇到可重試錯誤時可以保持重試。Kafka的跨數據中心複製工具默認會進行無限制的重試。做爲一個高可用性的複製工具,它毫不會丟失消息。

要注意重試可能會致使消息重複,例如因爲網絡問題消息寫入後生產者沒有收到確認消息,生產者重試。這種狀況下broker會收到兩個相同的消息。

6.4.3額外的錯誤處理

使用生產者內置的重試機制能夠在不形成消息丟失的狀況下輕鬆處理大部分錯誤,不過對於開發人員來講,仍然須要處理其它類型的錯誤,包括:

不可重試的broker錯誤,例如消息大小錯誤,認證錯誤;

在消息發送以前的錯誤,如序列化錯誤;

在生產者達到重試次數上限時或在消息佔用的內存達到上限時發生的錯誤。

若是錯誤處理只是爲了重發,那麼最好使用生產者內置的重試機制。

6.5在可靠的系統裏使用消費者

只有那些被提交到Kafka的數據,也就是已經被寫入到全部同步副本的數據,對消費者時可用的,這意味着消費者獲得的消息已經具有了一致性。消費者惟一要作的事跟蹤哪些消息是已經讀取過的,哪些是尚未讀取過的。這是在讀取消息時不丟失消息的關鍵。

從分區讀取數據時,消費者會獲取一批事件,檢查其中最大的偏移量,而後從這個偏移量開始讀取另一批事件,這樣能夠保證消費者總能以正確的順序獲取新數據,不會錯過任何事件。

若是消費者提交了偏移量卻未能處理完消息,那麼就可能形成消息丟失,這也是消費者丟失消息的主要緣由,所以咱們會很是重視偏移量的提交時間點和方法。

已提交偏移量是指消費者發送給Kafka的偏移量,用於確認它已經收到並處理好的消息位置。

6.5.1消費者的可靠性配置

爲了保證消費者的可靠性,有4個很是重要的配置參數。

1.group.id

若是兩個消費者具備相同的group.id,而且訂閱了同一個主題,那麼每一個消費者會分到主題分區的一個子集,若是但願消費者能夠看到主題的全部消息,那麼須要爲它們設置惟一的group.id

2.auto.offset.reset

這個參數指定了沒有偏移量可提交時,消費者作什麼?有兩種配置:earliest消費者從分區的開始位置讀取數據,latest消費者從分區的末尾讀取數據,這樣能夠減小重複處理消息,但可能錯過一些消息。

3.enable.auto.commit

可讓消費者自動提交偏移量,也能夠在代碼裏手動提交偏移量。自動提交的好處是實現消費者邏輯時能夠少考慮一些問題。缺點是沒法控制重複處理消息,若是把消息交給另一個後臺線程去處理,自動提交機制可能在消息尚未處理完畢就提交偏移量。

4.auto.commit.interval.ms

與第三個參數有直接聯繫,若是選擇了自動提交,能夠經過該參數配置自動提交的頻度,默認是5秒提交一次。

6.5.2顯式提交偏移量

1.老是在處理完事件後再提交偏移量

若是全部處理在輪詢裏完成,而且不須要在輪詢之間維護狀態,那麼可使用自動提交,或者輪詢結束後進行自動提交。

2.提交頻率是性能和重複消息數量之間的權衡

能夠在一個循環屢次提交偏移量,或者多個循環只提交一次,這取決於你在性能和重複之間的權衡

3.確保對提交的偏移量內心有數

處理完消息後再提交偏移量是很是關鍵的——不然會致使消費者錯過消息

4.再均衡

通常要在分區被撤銷以前提交偏移量,並在分配到新分區時清理以前的狀態。

5.消費者可能須要重試

假設要把Kafka數據寫到數據庫,不過那時數據庫不可用,想稍後重試,要注意,你提交的是偏移量,不是確認,能夠採用兩種辦法解決:

一是提交最後一個處理成功的偏移量,而後把尚未處理的消息保存到緩衝區,調用消費者的pause方法來確保其它輪詢不會返回數據,在保持輪詢的同時嘗試從新處理,若是重試成功,或者重試次數到達上限並決定放棄,那麼把錯誤消息記錄下來並丟棄消息,而後調用resume方法讓消費者從輪詢繼續獲取新數據。

二是遇到可重試錯誤時,把錯誤寫入一個獨立主題,而後繼續。一個獨立的消費者羣組複製從該主題讀取錯誤消息,並進行重試,或者使用其中一個消費者同時從該主題讀取錯誤並進行重試,不太重試時須要暫停該主題。這個模式有點像dead-letter-queue.

6.消費者可能須要維護狀態

若是須要在多個輪詢之間維護狀態,有一個辦法是提交偏移量同時把最近計算的結果寫到一個主題上,消費者線程重啓以後,它就能夠拿到最近的平均數接着計算,這個問題很複雜,建議使用KafkaStream。

7.長時間處理

若是處理數據須要很長時間,暫停輪詢不能超過幾秒,即便不想獲取更多數據,也要保持輪詢,這樣客戶端才能向broker發送心跳。這種狀況下,一種常見的作法是使用一個線程池來處理數據,由於使用多個線程能夠並行處理,從而加快速度。把數據交給線程池處理後,就能夠暫停消費者而後保持輪詢,但不獲取新數據,直到工做線程處理完成。繼續獲取新數據,由於消費者保持輪詢,心跳就會正常,就不會發生在均衡。

8.僅一次傳遞

實現僅一次處理最簡單最經常使用的辦法是把結果寫到一個支持惟一鍵的系統裏,好比鍵值存儲引擎,關係數據庫,elasticSearch或者其餘數據存儲引擎。這種狀況下,要麼消息自己包含一個惟一鍵(一般是這樣),要麼使用主題,分區和偏移量的組合建立一個惟一鍵——它們的組合能夠惟一標識一個Kafka記錄。若是出現重複記錄,只須要覆蓋原來的消息便可,就像沒有出現重複數據同樣。這個模式叫作冪等姓寫入,它是一種很常見也頗有用的模式。

若是寫入消息的系統支持事務,最簡單的使用關係數據庫,hdfs有一些被從新定義過的原子操做也常常用來達到相同目的。咱們把消息和偏移量放在同一個事物裏,這樣它們就能保持同步。消費者重啓時,就會獲取最近被處理過的消息的偏移量。而後調用seek方法從該偏移量繼續讀取數據。

6.6驗證系統的可靠性

建議作三個層面的驗證——配置驗證,應用程序驗證和生產環境的應用程序監控。

6.6.1驗證配置

從應用程序能夠很容易對broker和客戶端配置進行驗證,有如下兩方面緣由:

1.驗證配置是否知足你的需求

2.幫助理解系統的行爲,瞭解對Kafka基本準則的理解是否存在誤差,而後改進,理解這些準則是如何被應用到各類場景中的。

Kafka提供了兩個重要工具驗證配置:org.apache.kafka.tools包裏的VerifiableProducer和VerifiableConsumer這兩個類。咱們能夠從命令行容許這兩個類,或者把它們嵌入到自動化測試框架。

VerifiableProducer生成一系列消息,這些消息包含從1到你指定的某個數字,你可使用與生產者相同的方式配置VerifiableProducer,在運行VerifiableProducer時,它會把每一個消息是否成功發送到broker的結果打印出來。

VerifiableConsumer執行另外一種檢查,它讀取事件,並按照順序打印這些事件。他也會打印已提交的偏移量和再均衡的相關信息。

能夠考慮如下測試:

1.首領選舉,生產者和消費者恢復正常須要多久?

2.控制器選舉,重啓控制器系統須要多久恢復?

3.依次重啓,能夠重啓broker而不丟失數據嗎?

4.不徹底首領選舉測試,若是依次中止全部副本,而後啓動一個不一樣步的broker會發生什麼?要怎麼恢復正常?這樣作能夠接受嗎?

Kafka代碼庫包含了大量測試用例,它們使用VerifiableProducer和VerifiableConsumer來確保迭代的版本可以正常工做。

6.6.2應用程序驗證

應用程序的驗證包含檢查自定義的錯誤處理代碼,偏移量提交方式,再均衡監聽器和其它使用了Kafka客戶端的地方。

建議作以下測試:

1.客戶端從服務器斷開鏈接

2.首領選舉

3.依次重啓broker

4.依次重啓消費者

5.依次重啓生產者

看測試結果是否符合預期。

6.6.3在生產環境監控可靠性

首先Kafka的Java客戶端包含了JMX度量指標,這些指標能夠用於監控客戶端的狀態和事件。對於生產者來講最重要的指標時消息的error-rate和retry-rate,若是兩個指標上升,說明系統出現了問題。

除此以外,還要監控生產者日誌——發送消息的錯誤日誌被設爲WARN級別。

對於消費者來講最重要的指標時consumer-lag,這個指標代表了消費者的處理速度與最近提交到分區裏的偏移量之間還有多少差距。理想狀況下,該指標老是0,消費者總能讀到最新的消息。不過實際中,poll方法會返回不少消息,所以該指標會有波動,關鍵是確保消費者最終會遇上去,而不是越落越遠。

監控數據流是爲了確保全部生成的數據會被及時讀取,爲了確保數據可以及時讀取,須要知道數據是何時生成的。0.10.0版本的Kafka在消息裏增長了時間戳,代表了消息的生成時間。若是使用的是更早的客戶端,建議在消息里加入時間戳,應用程序名字和機器名,這樣有助於診斷問題。

爲了確保全部消息可以在合理時間被讀取,應用程序須要記錄生成消息的數量,而消費者須要記錄已經讀取消息的數量以及消息生成時間到當前時間的時間差

而後須要工具來比較生產者和消費者記錄的消息數量(爲了確保沒有丟失消息),確保這二者之間的時間差不會超出咱們容許的範圍。

相關文章
相關標籤/搜索