ceph 網絡模塊

代碼入手方式:

1. osd的網絡通信messenger在old.h中定義,如下圖所示

 

2. 然後查看cluster_messenger的創建。

 

3. 再來查看internal_messenger的由來,是osd構造函數賦值的。

 

4. 最後看看ms_cluster的創建,在osd初始化的時候創建的。

 

以上,就是cluster_messenger是如何跟IP綁定的過程。

5. 然後通過這個messenger發送網絡消息即可。

 

6. 發送pg info時候調用的就是cluster網絡,其他消息發送流程也是一樣的。

 

備註:補充一下大神寫的網絡基礎知識,引用於《網絡層的處理》

在現在的網絡編程實現中,大多數項目都會採用基於事件通知的異步網絡 IO 方式來實現。目前無論是 Epoll 還是 Kqueue 都已經成爲主流網絡編程知識,本文就不介紹這些基本概念和使用了。主要圍繞目前 Ceph 的網絡層實現來解構和探討如何重構。

總體設計

在 Ceph 項目伊始的 06 年,那時候在網絡編程還是線程模型當道的年頭,Ceph 採用了簡單粗暴的採用了每兩個線程對應一個終端的方式,其中一個用於監聽和讀取該終端的讀事件,另一個用於寫事件。我們可以簡單稱這兩個線程爲一條連接的讀線程和寫線程。讀線程得到請求以後會解析網絡流並開始構建消息,然後派發到後面的 Dispatcher。寫線程在大部分時候會處於 Sleep 狀態,直到有新的消息需要發送纔會被喚醒。

Ceph 在目前的網絡層面上有三個重要概念,分別是 Messenger,Pipe,Connection。Messenger 實際上可以理解爲一個監聽地址和多個連接的集合。比如每個 OSD 中會有 cluster_messenger 和 public_messenger,顧名思義 cluster_messenger 負責給 OSD 與其他 OSD 和 Monitor 的通信並提供了一個監聽地址,public_messenger 負責與客戶端的通信並提供了一個面向客戶端的監聽地址。因此 cluster_messenger 中負責的連接會全部是面向其他 OSD 或者 Monitor 的連接。Pipe 實際上是一個 Session 的載體,爲了解決網絡連接不穩定或者臨時閃斷連接的問題,Pipe 會一直維護面向一個終端地址的會話狀態,如類似 TCP 包序號的消息序號和發送隊列。Connection 就是一個 socket 的 wrapper,它從屬於某一個 Pipe。

一個會話的邏輯

 

上圖主要聚焦 OSD 端的網絡邏輯,客戶端實際上是一模一樣的網絡實現只是不會擁有一個監聽端口。網絡上層的業務實際上只需要關注一個邏輯上的持久會話,通過 Dispatcher 得到消息處理,然後通過 Connection 接口把消息放到發送隊列發送。

 

上面這個圖主要描述了一個會話建立的流程,其中 banner 類似於一個宣告,然後互相瞭解對方的地址信息。主要邏輯在於 connection message 中的信息,服務器端會校驗這些連接信息並確保面向這個地址的連接只有一條,如果 client 發送了一個已經建立會話的地址,服務器端會考慮是否需要替換或者廢棄當前連接。另外在這裏會需要確定是否要發送驗證信息(圖中省略)。在會話成功後,實際上就對雙方當前的 Pipe 狀態達成了一致。

線程問題

實際上我們從中很容易發現這個線程模型是存在重大問題的,也就是隨着一個實體(如 OSD)的增加會線性增加一個實體的線程數目。線程的增加會導致嚴重的 Context Switch 損耗,線程級的 Context Switch 大概在 us 級別,會影響延遲敏感性應用的性能並且對系統造成資源壓力。

因此,在去年 Accelio 提交了基於開源的一個 RPC 庫的高性能的 Ceph 網絡層實現,另外,作者也在上個月完成了一個基於事件通知的異步 Messenger 實現,主要將之前同步的 SimpleMessenger 改造成狀態機並且實現了一個簡單的事件管理器。相對於 accelio 的實現,本人的實現希望避免引入一個巨大的 RPC 庫造成諸多不便,會大大限制 Ceph 在網絡層實現上的範圍,也可能會引來第三方庫使用的問題。而實際上 Ceph 只需要一個簡單的事件管理器即可高效的達到目的。

 

0人點贊

 

日記本

 



作者:620T
鏈接:https://www.jianshu.com/p/a7ed0c75ba76
來源:簡書
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

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