Kafka系列第4篇:消息發送時,網絡“偷偷”幫忙做的那點事兒

前言

上篇文章講述了消息從生產到寫入到 Broker 的 partition 上背後發生的故事,並提出了消息發送的網絡模型的問題。本篇文章我們來嘗試揭開其背後的神祕面紗,耐心看完你一定會有所收穫。

文章概覽

  1. Sender 線程的建連準備階段和發送網絡請求兩階段。

  2. Selector 選擇器處理網絡請求過程。

Sender 線程的兩階段

上篇文章結尾提到了三個重要的方法,分別是 ready()、send()、poll()。其中 ready()和 send()可以理解爲第一階段,即建連準備階段;poll()可以理解爲第二階段,即發送網絡請求階段。接下來對這兩階段做深入研究。

階段流程說明
  • ready()階段: 遍歷節點列表,查詢當前是否已建立連接,若已完成建連,則認爲該節點可用;若還未建連,則判斷該節點是否可以被連接,若是則建連。對於不可建連和正在建連的節點暫時還不能參與網絡數據傳輸請求。

  • send()階段: 通過 ready()階段拿到了已經完成建連的節點,然後遍歷節點,判斷當前節點是否可以被髮送數據,若可以則將當前節點對應的 RequestChannel 加入到 InFlightRequest 雙端隊列中去。爲什麼要將 RequestChannel 加入到一個雙端隊列中去呢?因爲服務端爲了保證服務端性能,一個服務端在同一時刻只能被一個客戶端請求連接,如果上一個客戶端請求還未完成,則不允許新的客戶端請求連接。當客戶端請求接收到服務端響應後,將對應的客戶端請求從 InFlightRequest 隊列中移除。

  • poll()階段: 通過 ready()和 send()兩階段,完成了數據準備和可用節點檢查。在上一篇中我們介紹到客戶端是按照 Broker 分組,每組建立一個網絡連接請求,每個網絡連接請求管理多個網絡連接通道,從而形成了一個連接同時與多個 Broker 進行網絡數據傳輸。poll()方法採用了選擇器(Selector)模式來處理這種網絡模型,其底層是使用 Java 的 NIO 來實現的。

簡單介紹下 Java NIO 的幾個組件,想要深入瞭解的同學通過 Google 去了解。

  • SocketChannel: 客戶端網絡連接通道,在此通道上可進行數據的讀寫操作,比如將數據寫入到通道中和將數據從通道中讀取出來操作。

  • Selector: 選擇器,通道是需要註冊到 Selector 選擇器上的,同時在註冊後會返回一個選擇器建,Selector 會通過選擇器鍵來監聽讀寫事件。

  • SelectorKey: 選擇器鍵,通道註冊到選擇器上,同時返回了選擇器鍵,從而使得選擇器鍵和通道建立了關係。

以上三者之間的關係如下:

當有讀寫請求發生時,Selector 可以通過 SelectorKey 拿到對應的 SocketChannel,從而在 SocketChannel 上進行數據的讀寫請求。

Selector 選擇器的實現原理

關於 Selector 選擇器,我們從兩個方面來介紹其背後發生了那些故事,分別是 建連過程和讀寫操作流程。

Selector 建連過程分析

Kafka建連過程

從上圖可以看出,首先打開一個客戶端連接 SocketChannel,然後對 Socket 設置一些參數,比如寫入數據大小、接受數據大小、TCP 延遲等等參數。然後使用 SocketChannel 嘗試建立連接。建連完成後將 SocketChannel 註冊到 Selector 選擇器上,並返回 SelectorKey。最後將 SocketChannel 包裝成 KafkaChannel,並使用 SelectorKey 與 KafkaChannel 進行關聯;爲啥會出現 KafkaChannel 了呢?因爲 Kafka 框架爲了屏蔽 SocketChannel 內部的細節操作,所有就對 SocketChannel 進行了一層包裝方便 Kafka 客戶端操作。

附上源碼供大家參考研究

Selector 選擇器讀寫操作流程

讀寫流程圖

從上圖可以看出,以寫操作爲例,客戶端輪詢到寫請求時,首先獲取寫請求對應的 SelectorKey,從而拿到對應的 KafkaChannel;然後將要發送的數據寫入到 KafkaChannel 中;然後通過傳輸協議將數據交由底層的 SocketChannel;最後由 SocketChannel 將數據發送給 Broker,完成數據的發送請求。該過程中需要注意一個問題,Broker 在同一時間只能處理一個客戶端請求,如果當前客戶端請求還沒被被處理完,下一個請求是不能被髮送給服務端的。

總結

以上即爲數據從客戶端發送到服務端背後相關的網絡操作故事;到此,關於生產者客戶端的相關操作暫且分析到這裏,關於客戶端冪等性、消息重發等問題我們在後面專門用篇幅來講解。下篇文章我們來分析一下消費者端消費消息背後的一些故事,敬請期待。

覺得文章不錯,轉發給更多的朋友們吧

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