MongoDB請求處理流程
Mongodb多存儲引擎支持機製介紹了Mongodb存儲層創建數據庫、創建集合、插入文檔等數據庫操作接口,本文將介紹mongodb處理客戶端請求的模型。
Mongod在啟動時會調用createServer創建一個PortMessageServer對象,其繼承MessageServer和Listener兩個類,並依賴MyMessageHandler來處理請求。
class PortMessageServer: public MessageServer, public Listener {
public:
void accepted(boost::shared_ptr<Socket> psocket, long long connectionId );
void setupSockets();
void run();
private:
MessageHandler* _handler;
};
PortMessageServer
- 調用setupSockets為mongod配置的每個地址創建一個socket,並調用bind綁定地址。
- 調用initAndListen監聽所有的地址,調用select等待監聽fd上發生連接事件,調用accept係統調用接受新的連接請求,並為每個新連接創建一個線程,該線程執行handleIncomingMsg方法,不斷處理該連接上的客戶端請求。
handleIncomingMsg
- 連接建立時,調用MyMessageHander::connected方法,初始化一個新的Client對象,Client對象包含DB操作的上下文。
- 不斷調用recv從連接上讀取請求,當讀取到一個完整請求時,其將請求反序列化為一個Message對象,並調用MyMessageHandler::process方法處理請求,處理完後給客戶端發送應答。
- 連接斷開時,調用MyMessageHander::disconnected方法停止該連接對應的線程,釋放Client對象。
MyMessageHandler::process
調用assembleResponse方法,從Message對象裏獲取請求類型(參考Mongdb協議),根據請求類型進行響應的處理。
- 如果為請求dbQuery,調用receivedQuery處理
- 如果為請求dbInsert,調用receivedInsert處理
- 如果為請求dbUpdate,調用receivedUpdate處理
- 如果為請求dbDelete,調用receivedDelete處理
- ......
上述各種請求最終會調用Database類的接口來處理;比如receivedInsert,會先根據Database回去對應的Collection對象,最後調用insertDocument往集合中插入文檔。請求處理完後,給客戶端發送應答消息。
問題分析
select的使用
mongod調用select時,fdset裏隻會加入監聽fd,而監聽的地址通常很少,故不存在效率問題。
thread per client模型
mongod為每個連接創建一個線程,創建時做了一定優化,將棧空間設置為1M,減少了線程的內存開銷。當線程太多時,線程切換的開銷也會變大,但因為mongdb後端是持久化的存儲,切換開銷相比IO的開銷還是要小得多。
最後更新:2017-04-01 13:37:08
上一篇:
PostgreSQL 妙用explain Plan Rows快速估算結果集數量
下一篇:
Greenplum 注意對其數據類型,否則優化器讓你好看
C++編程規範之3:使用版本控製係統
徹底卸載oracle
PostgreSQL vs Greenplum Hash outer join (hash表的選擇)
Elasticsearch 默認配置 IK 及 Java AnalyzeRequestBuilder 使用
網聚生態力量,打造特色小鎮 ——新外貿服務雲讓貿易小鎮更美好
Spring Boot 配置文件 – 在坑中實踐
Tomcat 7之無需JDK隻需JRE與無需web.xm及J2SE 6.0之真實與謊言?
快速計算Distinct Count
java 遍曆map對象的四種方式
後台開發:核心技術與應用實踐2.3 類的多態