kafka叢集Producer基本資料結構及工作流程深入剖析-kafka 商業環境實戰

開心雲技術社群發表於2018-12-02

本套技術專欄是作者(秦凱新)平時工作的總結和昇華,通過從真實商業環境抽取案例進行總結和分享,並給出商業應用的調優建議和叢集環境容量規劃等內容,請持續關注本套部落格。期待加入IOT時代最具戰鬥力的團隊。QQ郵箱地址:1120746959@qq.com,如有任何學術交流,可隨時聯絡。

1 Producer端基本資料結構

  • ProducerRecord: 一個ProducerRecord表示一條待傳送的訊息記錄,主要由5個欄位構成:

      topic          所屬topic
      partition      所屬分割槽
      key            鍵值
      value          訊息體
      timestamp      時間戳
    複製程式碼
  • RecordMetadata: Kafka伺服器端返回給客戶端的訊息的後設資料資訊,前3項相對比較重要,Producer端可以使用這些訊息做一些訊息傳送成功之後的處理。

      offset                   該條訊息的位移
      timestamp                訊息時間戳
      topic + partition        所屬topic的分割槽
      checksum                 訊息CRC32碼
      serializedKeySize        序列化後的訊息鍵位元組數
      serializedValueSize      序列化後的訊息體位元組數
    複製程式碼

2 Producer端訊息傳送流程

kafka叢集Producer基本資料結構及工作流程深入剖析-kafka 商業環境實戰

  • 在send()的傳送訊息動作觸發之前,通過props屬性中指定的servers連線到broker叢集,從Zookeeper收集叢集Metedata資訊,從而瞭解哪些broker掌管哪一個Topic的哪一個partition,以及brokers的健康狀態。

  • 下面就是流水線操作,ProducerRecord物件攜帶者topic,partition,message等資訊,在Serializer這個“車間”被序列化。

  • 序列化過後的ProducerRecord物件進入Partitioner“車間”,按照上文所述的Partitioning 策略決定這個訊息將被分配到哪個Partition中。

  • 確定partition的ProducerRecord進入一個緩衝區,通過減少IO來提升效能,在這個“車間”,訊息被按照TopicPartition資訊進行歸類整理,相同Topic且相同parition的ProducerRecord被放在同一個RecordBatch中,等待被髮送。什麼時候傳送?都在Producer的props中被指定了,有預設值,顯然我們可以自己指定。

      (1) batch.size:設定每個RecordBatch可以快取的最大位元組數 
      (2) buffer.memory:設定所有RecordBatch的總共最大位元組數 
      (3) linger.ms設定每個RecordBatch的最長延遲傳送時間 
      (4) max.block.ms 設定每個RecordBatch的最長阻塞時間 
    複製程式碼
  • 一旦,當單個RecordBatch的linger.ms延遲到達或者batch.size達到上限,這個 RecordBatch會被立即傳送。另外,如果所有RecordBatch作為一個整體,達到了buffer.memroy或者max.block.ms上限,所有的RecordBatch都會被髮送。

  • ProducerRecord訊息按照分配好的Partition傳送到具體的broker中,broker接收儲存訊息,更新Metadata資訊,同步給Zookeeper。

  • Producer端其他優化點:

      (5) acks:Producer的資料確認阻塞設定,0表示不管任何響應,只管發,發完了立即執行下個任務,這種方式最快,但是很不保險。1表示只確保leader成功響應,接收到資料。2表示確保leader及其所有follwer成功接收儲存訊息,也可以用”all”。
      (6) retries:訊息傳送失敗重試的次數。
      (7) retry.backoff.ms:失敗補償時間,每次失敗重試的時間間隔,不可設定太短,避免第一條訊息的響應還沒返回,第二條訊息又發出去了,造成邏輯錯誤。
      (8) max.in.flight.request.per.connection:同一時間,每個Producer能夠傳送的訊息上限。
      (9) compression.type  producer所使用的壓縮器,目前支援gzip, snappy和lz4。壓縮是在使用者主執行緒完成的,通常都需要花費大量的CPU時間,但對於減少網路IO來說確實利器。生產環境中可以結合壓力測試進行適當配置
    複製程式碼

3 訊息緩衝區(accumulator)再剖析

  • producer建立時會建立一個預設32MB(由buffer.memory引數指定)的accumulator緩衝區,專門儲存待傳送的訊息。

  • 該資料結構中還包含了一個特別重要的集合資訊:訊息批次資訊(batches)。該集合本質上是一個HashMap,裡面分別儲存了每個topic分割槽下的batch佇列,即前面說的批次是按照topic分割槽進行分組的。這樣發往不同分割槽的訊息儲存在對應分割槽下的batch佇列中。

  • 假設訊息M1, M2被髮送到test的0分割槽但屬於不同的batch,M3分送到test的1分割槽,那麼batches中包含的資訊就是:{"test-0" -> [batch1, batch2], "test-1" -> [batch3]}

  • 每個batch中最重要的3個元件包括:

      compressor: 負責執行追加寫入操作
      batch緩衝區:由batch.size引數控制,訊息被真正追加寫入到的地方
      thunks:儲存訊息回撥邏輯的集合
    複製程式碼
  • 本套技術專欄是作者(秦凱新)平時工作的總結和昇華,通過從真實商業環境抽取案例進行總結和分享,並給出商業應用的調優建議和叢集環境容量規劃等內容,請持續關注本套部落格。期待加入IOT時代最具戰鬥力的團隊。QQ郵箱地址:1120746959@qq.com,如有任何學術交流,可隨時聯絡。

    kafka叢集Producer基本資料結構及工作流程深入剖析-kafka 商業環境實戰

  • Sender執行緒自KafkaProducer建立後就一直都在執行著 。它的工作流程基本上是這樣的:

      (1)不斷輪詢緩衝區尋找已做好傳送準備的分割槽 
      (2)將輪詢獲得的各個batch按照目標分割槽所在的leader broker進行分組
      (3)將分組後的batch通過底層建立的Socket連線傳送給各個broker
      (4)等待伺服器端傳送response回來
    複製程式碼

kafka叢集Producer基本資料結構及工作流程深入剖析-kafka 商業環境實戰

  • Sender執行緒會傳送PRODUCE請求給對應的broker,broker處理完畢之後傳送對應的PRODUCE response。一旦Sender執行緒接收到response將依次(按照訊息傳送順序)呼叫batch中的回撥方法

kafka叢集Producer基本資料結構及工作流程深入剖析-kafka 商業環境實戰

4 總結

  • Sender執行緒自KafkaProducer建立後就一直都在執行著,單個RecordBatch的linger.ms延遲到達或者batch.size達到上限,作為後臺執行緒就會檢測到立即傳送。
  • accumulator緩衝器按照Topic partion進行分組,來進行集中向某一個Broker傳送。
  • 本文通過學習胡夕的相關技術部落格和書籍,進行的學習筆記總結,辛苦成文,實屬不易,各自珍惜,謝謝。
  • 秦凱新 於深圳 201812030018

相關文章