深入理解Kafka設計:高效能伺服器模型(1)

weixin_33936401發表於2017-06-11
版權宣告:本文為博主原創文章,未經博主允許不得轉載。

摘要

Kafka作為一個高效能的訊息中介軟體,其高效的原因可以歸納為以下這幾個方面:

  • 高效能伺服器模型
  • PageCache
  • Zero-Copy

本文將從原始碼層面(基於0.8.2.X)介紹Broker的高效能伺服器模型是如何實現的。

高效能伺服器模型

Kafka並沒有採用netty或mina等第三方網路應用框架,而是直接了當的使用了NIO來實現伺服器,並在使用了IO多路複用以及多執行緒Reactor模式,這種設計的優勢是很容易實現,同時也很快。

官方並沒有在伺服器設計上詳細展開,因此本文將從邏輯結構和原始碼方面來分析這個方面的設計,藉此瞭解一下NIO伺服器設計的方法及一些細節。

SocketServer作為Kafka的NIO伺服器實現,其邏輯結構圖如下:


6181648-126ce3ba23d8515b.png
SocketServer邏輯架構圖.png

重要元件

  1. Acceptor執行緒:主要負責監聽並接受客戶端(包括但不限於Producer,Consumer,Broker,Controller,AdminTool)的連線請求,新連線建立以後指定某個Processor去處理。

  2. Processor執行緒:負責資料讀寫,連線關閉的處理執行緒,其數目由配置num.network.threads決定,預設是3個。每個Processor內部都有自己的newConnections佇列和selector。

    • newConnections:一個無界的SocketChannel佇列,存放新建立的連線,將Acceptor與Processor的功能解藕。
    • selector:只使用一個selector來支撐大量連線的事件管理很容易遇到瓶頸,而多個selector並存的結構可以均衡的管理大量連線。
  3. RequestChannel:包含一個RequestQueue和多個ResponseQueue。它是網路層與API層交換資料的地方,同時也使得兩者邏輯解藕和非同步化。

    • RequestQueue:所有的請求都會被封裝成Request並放入RequestQueue中,佇列大小預設500。
    • ResponseQueue:每個Processor都會有對應ResponseQueue,KafkaApis業務邏輯處理完成後,會將返回結果封裝成Response,接著由相應的Processor來處理該response。而且設計上必須保證一對Request和Response都要由同一個Processor來處理,因為只有這個Processor擁有該通訊連線。
  4. KafkaRequestHandler執行緒:這是真正的業務邏輯處理執行緒,其數目由配置num.io.threads決定,預設是8個。每個Handler執行緒都在不斷的從RequestChannel.RequestQueue中獲取新的請求,那些負載輕的執行緒才有可能搶到新的請求,因為負載重的執行緒(也許正在進行IO)還沒有空閒來接受下一個新的請求,所以這也算一個潛在的負載均衡策略吧。

  5. KafkaApis:Broker的所有業務邏輯都定義在這裡,其handle方法會根據Request物件的requestId(對應各種業務邏輯,其定義可以在類RequestKeys中看到),將請求分發給對應的業務邏輯處理方法。當處理完成以後,可能會將處理結果封裝成Response返回給對應的RequestChannel.ResponseQueue。

總結

這一節主要是從總體上介紹了Broker伺服器模型的各種重要的元件,下一節我們將結合原始碼分析一下請求處理的流程:
深入理解Kafka設計:高效能伺服器模型(2)

相關文章