Mongodb請求處理流程

發表於2015-08-20

Mongodb多儲存引擎支援機制介紹了Mongodb儲存層建立資料庫、建立集合、插入文件等資料庫操作介面,本文將介紹mongodb處理客戶端請求的模型。

Mongod在啟動時會呼叫createServer建立一個PortMessageServer物件,其繼承MessageServer和Listener兩個類,並依賴MyMessageHandler來處理請求。

 

PortMessageServer

  1. 呼叫setupSockets為mongod配置的每個地址建立一個socket,並呼叫bind繫結地址。
  2. 呼叫initAndListen監聽所有的地址,呼叫select等待監聽fd上發生連線事件,呼叫accept系統呼叫接受新的連線請求,併為每個新連線建立一個執行緒,該執行緒執行handleIncomingMsg方法,不斷處理該連線上的客戶端請求。

handleIncomingMsg

  1. 連線建立時,呼叫MyMessageHander::connected方法,初始化一個新的Client物件,Client物件包含DB操作的上下文。
  2. 不斷呼叫recv從連線上讀取請求,當讀取到一個完整請求時,其將請求反序列化為一個Message物件,並呼叫MyMessageHandler::process方法處理請求,處理完後給客戶端傳送應答。
  3. 連線斷開時,呼叫MyMessageHander::disconnected方法停止該連線對應的執行緒,釋放Client物件。

MyMessageHandler::process

呼叫assembleResponse方法,從Message物件裡獲取請求型別(參考Mongdb協議),根據請求型別進行響應的處理。

  1. 如果為請求dbQuery,呼叫receivedQuery處理
  2. 如果為請求dbInsert,呼叫receivedInsert處理
  3. 如果為請求dbUpdate,呼叫receivedUpdate處理
  4. 如果為請求dbDelete,呼叫receivedDelete處理
  5. ……

上述各種請求最終會呼叫Database類的介面來處理。比如receivedInsert,會先根據Database回去對應的Collection物件,最後呼叫insertDocument往集合中插入文件。請求處理完後,給客戶端傳送應答訊息。

 

問題分析

select的使用

mongod呼叫select時,fdset裡只會加入監聽fd,而監聽的地址通常很少,故不存在效率問題。

thread per client模型

mongod為每個連線建立一個執行緒,建立時做了一定優化,將棧空間設定為1M,減少了執行緒的記憶體開銷。當執行緒太多時,執行緒切換的開銷也會變大,但因為mongdb後端是持久化的儲存,切換開銷相比IO的開銷還是要小得多。

相關文章