使用kafka收發大消息的一些思考 1. 背景 2. 配置 2.1 生產者與消費者的配置 2.2 kafka服務器端配置 3. 測試情況 4. 思考

1. 背景

  項目中有這樣一個需求:兩個服務之間需要傳遞視頻監控平臺的設備及分組信息。一個視頻監控平臺中通常有10萬數量級的監控設備信息,每個設備的詳細信息可能有二三十個字段,再加上分組信息,傳遞的信息量接近200M左右。以前使用發送多包消息的方式傳遞,這樣發送方與接收方需要以事務的方式處理消息,如接收方沒有收完整,就需要等待超時。如果傳輸過程中產生了丟包,則發送方需要重發,發送方與接收方的邏輯就變得比較複雜。
  目前我們使用kafka作爲項目中的消息中間件,考慮將所有發送的設備信息打成一包消息收發,這樣處理上變得簡單。
  kafka官方推薦使用消息大小不超過1M時吞吐量最佳。要發送達200M的消息,需要在服務器端,及生產者端及消費者端做一些配置與策略。

2. 配置

2.1 生產者與消費者的配置

  需要設置生產者和消費者的配置以接收和發送大消息,在項目的springboot工程中,application.yml文件配置如下:

 kafka:
    producer:
      bootstrap-servers: 172.16.64.159:9092
      buffer-memory: 536870912
      properties:
        request.timeout.ms: 900000
        max.request.size: 536870912 
        compression.type: gzip 
      
      
    consumer:
      bootstrap-servers: 172.16.64.159:9092
      auto-offset-reset: latest
      properties:
        max.poll.records: 1
        request.timeout.ms: 900000
        fetch.max.bytes: 536870912
        max.partition.fetch.bytes: 536870912 
      enable-auto-commit: true
     

  這裏生產者的buffer-memory被設爲500M;消息的壓縮類型被設置爲gzip,可保證傳輸與持久化時壓縮數據量;由於發送消息的時間可能會因消息量變長,因此請求超時時間設置爲900秒。消費者的max.poll.records被設爲1,表示每次只取一個消息;同樣,fetch.max.bytes和max.partition.fetch.bytes都設置爲500M。

2.2 kafka服務器端配置

  kafka服務器 端的配置文件也需要修改,對server.properties配置文件配置項更改如下:

message.max.bytes=536870912
replica.fetch.max.bytes=536870912
request.timeout.ms=900000

# The send buffer (SO_SNDBUF) used by the socket server
socket.send.buffer.bytes=1024000

# The receive buffer (SO_RCVBUF) used by the socket server
socket.receive.buffer.bytes=1024000

# The maximum size of a request that the socket server will accept (protection against OOM)
socket.request.max.bytes=536870912

3. 測試情況

  從測試情況來看,使用壓縮機制以後,150M的JSON格式消息可壓縮到十分之一,在應用服務與kafka服務器在同一局域網情況下,收發時間並不長。但在應用服務消費時,由於解壓消息,反序列化消息到對象,基本上會消耗至少3倍消息的堆內存,使用jconsole監控,如下圖所示:



  可以看到CPU和堆內存出現幾次峯值的地方都是在消費大消息時產生,若JVM初始堆內存設置的不夠大或已經使用較多,會出現OOM的錯誤,因此建議在每次消費大消息之後手工GC一下(system.gc())。

4. 思考

  由於我們的項目每天只同步一次監控平臺設備信息,因此kafka每天只收發大消息一次,系統還可支撐。如果要頻繁收發這種方法不可取,容易引起應用OOM,和kafka的崩潰與效率低下。其實我認爲使用折中方案,將應用的大消息按邏輯劃分爲多個包,包的數目在10個左右,包的大小在10M左右,這樣在效率與系統穩定性方面會更好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章