MongoDB技術分析(2)-Mongos 請求處理邏輯
前面介紹了TransportLayer作為MongoDB的網路服務端處理模塊,負責和客戶端的網路請求交互。那麼當TransportLayer接收到客戶請求後,MongoDB怎麼進一步進行業務處理呢?本文以查詢請求為例介紹mongos怎麼把請求轉發到shard server,並正確處理查詢結果的。
請求處理狀態機
TransportLayer接收到新連接後,會創建專門的conn線程負責處理該連接的後續所有請求,具體邏輯在ServiceEntryPointMongos類的_sessionloop函數中,根據請求的類型循環「收包,處理,迴響應」三個步驟,總結狀態機轉換關係如下:
具體到Process業務處理裡面,會進一步區分消息類型並走不同處理邏輯,主要分為:查詢類(queryop/getmore), 更新類(insert/update/delete),killcursors,以及其他ClientCommand這幾種類型。
這幾類命令的前半段處理流程基本類似,包括鑒權,語法判斷,根據分區視圖查找本次操作涉及哪些shardserver,以及錯誤重試機制。後半段則和具體業務邏輯相關,存在較大差異。
查詢請求處理邏輯
因為是Sharding集群模式下的查詢,根據查詢條件的不同,可能會涉及到多個Shard Server的數據,根據分區視圖確認涉及的Shard Server後,針對每個ShardServer生成一個查詢任務交由TaskExecutorPool執行。TaskExecutorPool負責維護mongos到ShardServer的長連接,並包含一個network線程池負責執行和ShardServer的網路交互。
Conn線程將查詢任務交由TaskExecutorPool任務隊列後,會wait到信號量上阻塞等待,TaskExecutorPool里的network線程完成查詢請求後,喚醒Conn線程進一步處理查詢結果。
Mongos為每一個Shard Server維護一個查詢結果緩存隊列,並按照Merge、Skip、Limit、RemoveSortKey的順序對查詢結果進行逐級處理後返回。其中Merge操作負責合併來自多個Shard Server的查詢結果,根據查詢條件是否要求排序有不同的處理邏輯:
- 需要排序:根據SortKey在多個隊列中找排最前面的,保證全局有序返回,緩存結果處理完了就觸發到對應ShardServer查詢數據;
- 不需要排序:一個Shard Server查詢結果返回完了再返回下一個ShardServer的查詢結果;
Mongos還會為每次查詢創建一個ClusterCursor,並維護和每個遠程Shard Server游標的對應關係,用於後續getmore操作進一步獲取數據。
總 結
Mongos作為Sharding集群的路由節點,負責根據查詢條件及分區視圖將查詢請求路由到對應的ShardServer,並正確處理來自多個ShardServer的查詢結果。對於查詢請求來說,使用pipeline的線程模型,conn線程負責和客戶端的交互,並把查詢請求交給network線程,network線程再負責和ShardServer的網路交互。
推薦閱讀:
※設計數據密集型應用-DDIA中文翻譯
※Linux安裝MySQL資料庫操作手冊
※Python徒手實現識別手寫數字—簡易圖片資料庫
※資料庫系統概念筆記(1)引言(上)
※手把手教您解決90%的自然語言處理問題