kafka冪等producer

         衆所周知,Kafka 0.11.0.0版本正式支持精確一次處理語義(exactly once semantics,下稱EOS)。Kafka的EOS主要體如今3個方面:html

  • 冪等producer:保證發送單個分區的消息只會發送一次,不會出現重複消息
  • 事務(transaction):保證原子性地寫入到多個分區,即寫入到多個分區的消息要麼所有成功,要麼所有回滾
  • 流處理EOS:流處理本質上可當作是「讀取-處理-寫入」的管道。此EOS保證整個過程的操做是原子性。注意,這隻適用於Kafka Streams

  上面3種EOS語義有着不一樣的應用範圍,冪等producr只能保證單分區上無重複消息;事務能夠保證多分區寫入消息的完整性;而流處理EOS保證的是端到端(E2E)消息處理的EOS。用戶在使用過程當中須要根據本身的需求選擇不一樣的EOS。如下是啓用方法:緩存

  • 啓用冪等producer:在producer程序中設置屬性enable.idempotence=true,但不要設置transactional.id。注意是不要設置,而不是設置成空字符串或"null"
  • 啓用事務支持:在producer程序中設置屬性transcational.id爲一個指定字符串(你能夠認爲這是你的事務名稱,故最好起個有意義的名字),同時設置enable.idempotence=true
  • 啓用流處理EOS:在Kafka Streams程序中設置processing.guarantee=exactly_once

 

所謂冪等producer指producer.send的邏輯是冪等的,即發送相同的Kafka消息,broker端不會重複寫入消息。同一條消息Kafka保證底層日誌中只會持久化一次,既不會丟失也不會重複。冪等性能夠極大地減輕下游consumer系統實現消息去重的工做負擔,所以是很是實用的功能。值得注意的是,冪等producer提供的語義保證是有條件的:ide

  • 單分區冪等性:冪等producer沒法實現多分區上的冪等性。如前所述,若要實現多分區上的原子性,須要引入事務
  • 單會話冪等性:冪等producer沒法跨會話實現冪等性。即便同一個producer宕機並重啓也沒法保證消息的EOS語義

  雖然有上面兩個限制,冪等producer依然是一個很是實用的新功能。下面咱們來討論下它的設計原理。若是要實現冪等性, 一般都須要花費額外的空間來保存狀態以執行消息去重。Kafka的冪等producer總體上也是這樣的思想。url

  首先,producer對象引入了一個新的字段:Producer ID(下稱PID),它惟一標識一個producer,當producer啓動時Kafka會爲每一個producer分配一個PID(64位整數),所以PID的生成和分配對用戶來講是徹底透明的,用戶無需考慮PID的事情,甚至都感覺不到PID的存在。其次,0.11 Kafka重構了消息格式(有興趣的參見Kafka 0.11消息設計),引入了序列號字段(sequence number,下稱seq number)來標識某個PID producer發送的消息。和consumer端的offset相似,seq number從0開始計數並嚴格單調增長。同時在broker端會爲每一個PID(即每一個producer)保存該producer發送過來的消息batch的某些元信息,好比PID信息、消息batch的起始seq number及結束seq number等。這樣每當該PID發送新的消息batch時,Kafka broker就會對比這些信息,若是發生衝突(好比起始seq number和結束seq number與當前緩存的相同),那麼broker就會拒絕此次寫入請求。假若沒有衝突,那麼broker端就會更新這部分緩存而後再開始寫入消息。這就是Kafka實現冪等producer的設計思路:1. 爲每一個producer設置惟一的PID;2. 引入seq number以及broker端seq number緩存更新機制來去重。.net

 

相關文章
相關標籤/搜索