1. 程式人生 > >kafka中處理超大訊息的一些考慮

kafka中處理超大訊息的一些考慮

 

 

時間:2015-02-01 00:38:26      閱讀:5854      評論:0      收藏:0      [點我收藏+]

標籤:

Kafka設計的初衷是迅速處理短小的訊息,一般10K大小的訊息吞吐效能最好(可參見LinkedIn的kafka效能測試)。但有時候,我們需要處理更大的訊息,比如XML文件或JSON內容,一個訊息差不多有10-100M,這種情況下,Kakfa應該如何處理?

針對這個問題,有以下幾個建議:

  1.   最好的方法是不直接傳送這些大的資料。如果有共享儲存,如NAS, HDFS, S3等,可以把這些大的檔案存放到共享儲存,然後使用Kafka來傳送檔案的位置資訊。
  2.   第二個方法是,將大的訊息資料切片或切塊,在生產端將資料切片為10K大小,使用分割槽主鍵確保一個大訊息的所有部分會被髮送到同一個kafka分割槽(這樣每一部分的拆分順序得以保留),如此以來,當消費端使用時會將這些部分重新還原為原始的訊息。
  3.   第三,Kafka的生產端可以壓縮訊息,如果原始訊息是XML,當通過壓縮之後,訊息可能會變得不那麼大。在生產端的配置引數中使用compression.codec和commpressed.topics可以開啟壓縮功能,壓縮演算法可以使用GZip或Snappy。

  
  不過如果上述方法都不是你需要的,而你最終還是希望傳送大的訊息,那麼,則可以在kafka中設定下面一些引數:

broker 配置:
 

  •     message.max.bytes (預設:1000000) – broker能接收訊息的最大位元組數,這個值應該比消費端的fetch.message.max.bytes更小才對,否則broker就會因為消費端無法使用這個訊息而掛起。
  •     log.segment.bytes (預設: 1GB) – kafka資料檔案的大小,確保這個數值大於一個訊息的長度。一般說來使用預設值即可(一般一個訊息很難大於1G,因為這是一個訊息系統,而不是檔案系統)。
  •     replica.fetch.max.bytes (預設: 1MB) – broker可複製的訊息的最大位元組數。這個值應該比message.max.bytes大,否則broker會接收此訊息,但無法將此訊息複製出去,從而造成資料丟失。


Consumer 配置:

 

  • fetch.message.max.bytes (預設 1MB) – 消費者能讀取的最大訊息。這個值應該大於或等於message.max.bytes。

所以,如果你一定要選擇kafka來傳送大的訊息,還有些事項需要考慮。要傳送大的訊息,不是當出現問題之後再來考慮如何解決,而是在一開始設計的時候,就要考慮到大訊息對叢集和主題的影響。
 

  • 效能: 根據前面提到的效能測試,kafka在訊息為10K時吞吐量達到最大,更大的訊息會降低吞吐量,在設計叢集的容量時,尤其要考慮這點。
  • 可用的記憶體和分割槽數:Brokers會為每個分割槽分配replica.fetch.max.bytes引數指定的記憶體空間,假設replica.fetch.max.bytes=1M,且有1000個分割槽,則需要差不多1G的記憶體,確保 分割槽數*最大的訊息不會超過伺服器的記憶體,否則會報OOM錯誤。同樣地,消費端的fetch.message.max.bytes指定了最大訊息需要的記憶體空間,同樣,分割槽數*最大需要記憶體空間 不能超過伺服器的記憶體。所以,如果你有大的訊息要傳送,則在記憶體一定的情況下,只能使用較少的分割槽數或者使用更大記憶體的伺服器。
  • 垃圾回收:到現在為止,我在kafka的使用中還沒發現過此問題,但這應該是一個需要考慮的潛在問題。更大的訊息會讓GC的時間更長(因為broker需要分配更大的塊),隨時關注GC的日誌和伺服器的日誌資訊。如果長時間的GC導致kafka丟失了zookeeper的會話,則需要配置zookeeper.session.timeout.ms引數為更大的超時時間。

一切的一切,都需要在權衡利弊之後,再決定選用哪個最合適的方案。