kafka知識體系-消息傳遞語義


本系列主要講解kafka基本設計和原理分析,分如下內容:

  1. 基本概念
  2. 消息模型
  3. kafka副本同步機制
  4. kafka文件存儲機制
  5. kafka數據可靠性和一致性保證
  6. kafka leader選舉
  7. kafka消息傳遞語義
  8. Kafka集群partitions/replicas默認分配解析

消息傳遞語義

消息傳遞保障

本節討論Kafka如何確保消息在producer和consumer之間傳輸。有以下三種可能的傳輸保障(delivery guarantee):

  • At most once: 消息可能會丟,但絕不會重復傳輸
  • At least once:消息絕不會丟,但可能會重復傳輸
  • Exactly once:每條消息肯定會被傳輸一次且僅傳輸一次

Kafka的消息傳輸保障機制非常直觀。當producer向broker發送消息時,一旦這條消息被commit,由於副本機制(replication)的存在,它就不會丟失。但是如果producer發送數據給broker后,遇到的網絡問題而造成通信中斷,那producer就無法判斷該條消息是否已經提交(commit)。雖然Kafka無法確定網絡故障期間發生了什么,但是producer可以retry多次,確保消息已經正確傳輸到broker中,所以目前Kafka實現的是at least once。

consumer從broker中讀取消息后,可以選擇commit,該操作會在Zookeeper中存下該consumer在該partition下讀取的消息的offset。該consumer下一次再讀該partition時會從下一條開始讀取。如未commit,下一次讀取的開始位置會跟上一次commit之后的開始位置相同。當然也可以將consumer設置為autocommit,即consumer一旦讀取到數據立即自動commit。如果只討論這一讀取消息的過程,那Kafka是確保了exactly once, 但是如果由於前面producer與broker之間的某種原因導致消息的重復,那么這里就是at least once。

考慮這樣一種情況,當consumer讀完消息之后先commit再處理消息,在這種模式下,如果consumer在commit后還沒來得及處理消息就crash了,下次重新開始工作后就無法讀到剛剛已提交而未處理的消息,這就對應於at most once了。

讀完消息先處理再commit。這種模式下,如果處理完了消息在commit之前consumer crash了,下次重新開始工作時還會處理剛剛未commit的消息,實際上該消息已經被處理過了,這就對應於at least once。

要做到exactly once就需要引入消息去重機制。

消息去重

如上一節所述,Kafka在producer端和consumer端都會出現消息的重復,這就需要去重處理。

Kafka文檔中提及GUID(Globally Unique Identifier)的概念,通過客戶端生成算法得到每個消息的unique id,同時可映射至broker上存儲的地址,即通過GUID便可查詢提取消息內容,也便於發送方的冪等性保證,需要在broker上提供此去重處理模塊,目前版本尚不支持。

針對GUID, 如果從客戶端的角度去重,那么需要引入集中式緩存,必然會增加依賴復雜度,另外緩存的大小難以界定。

不只是Kafka, 類似RabbitMQ以及RocketMQ這類商業級中間件也只保障at least once, 且也無法從自身去進行消息去重。所以我們建議業務方根據自身的業務特點進行去重,比如業務消息本身具備冪等性,或者借助Redis等其他產品進行去重處理。

高可用性配置

Kafka提供了很高的數據冗余彈性,對於需要數據高可靠性的場景,我們可以增加數據冗余備份數(replication.factor),調高最小寫入副本數的個數(min.insync.replicas)等等,但是這樣會影響性能。反之,性能提高而可靠性則降低,用戶需要自身業務特性在彼此之間做一些權衡性選擇。

要保證數據寫入到Kafka是安全的,高可靠的,需要如下的配置:

  • topic的配置:replication.factor>=3,即副本數至少是3個;2<=min.insync.replicas<=replication.factor
  • broker的配置:leader的選舉條件unclean.leader.election.enable=false
  • producer的配置:request.required.acks=-1(all),producer.type=sync

關於作者
愛編程、愛鑽研、愛分享、愛生活
關注分布式、高並發、數據挖掘
如需捐贈,請掃碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM