分片集群Mongos到Shard請求管理
MongoDB Sharded Cluster 原理
如果你還不了解 MongoDB Sharded cluster,可以先看文檔認識一下
Mongos 到 Shard請求管理
Mongos 是 MongoDB 分片集群的訪問入口,Mongos 收到 Client 訪問請求,會根據從 Config Server 獲取的路由表將請求轉發到後端對應的 Shard 上。
MongoDB-3.2 版本裏,Mongos 到 Shard 的請求由一組 TaskExecutor
來執行,TaskExecutor
可以簡單理解為一個任務調度器,當Mongos 需要向 Shard 發送請求時,會將調用 TaskExecutor::scheduleRemoteCommand
將請求扔給調度器,然後等待任務執行完成。
關於 TaskExecutor
Mongos 會根據請求的類型來選擇 TaskExecutor
,寫請求為了保證順序,每次都會選擇一個特定的 TaskExecutor
來執行任務。對於讀請求 Mongos 會采用 RoundRobin 的方式從一組TaskExecutor
中來選擇一個執行(默認會初始化CPU核數個 TaskExecutor
)。
TaskExecutor
包含2個重要的組成部分,負責調度邏輯的的 NetworkInterfaceThreadPool
, 以及負責實際IO操作的 NetworkInterfaceASIO
,使用了 boost::ASIO
,將所有IO操作都異步化,它包含一個連接池(ConnectionPool),用於管理 Mongos 到 Shard 的網絡連接。
當 Mongos 需要向 Shard 發請求時,就會從連接池裏獲取一個新的網絡連接,當沒有空閑的網絡連接時,則會創建新的網絡連接,所以當客戶端到 Mongos 並發請求很多時,Mongos 到 後端 Shard 的網絡連接也會很多。
關於連接池
ConnectionPool
針對每 個Shard 機器維護一個連接池,這個連接池包含4個小的池子,用於管理連接的生命周期。
- processingPool: 正在建立的連接
- readyPool:已經建立並且可用的連接
- checkoutPool: 正在使用的連接
- droppedProcessingPool:失敗的連接,需要釋放
連接池管理規則
- 連接池的總連接會控製在[minConnections, maxConnections]之間,默認為1和無窮大
- 當需要新建連接時,會發起一個新建連接的異步請求,並把請求放到
processingPool
- 當連接建立成功後,會把請求轉移到
readyPool
,readyPool 裏的連接可以直接用於服務新的請求 - 服務某個請求時會從
readyPool
裏取出連接後,會將連接轉移到checkOutPool
,標識為正在使用 - 連接使用完後,會歸還到
readyPool
; - 當遇到請求失敗 或 一個網絡連接空閑超過1分鍾時,會釋放連接
總結
Mongos 裏 TaskExecutor
的個數默認為機器的 CPU 核數,也可以在啟動時指定;如果一個機器上部署多個 MongoDB 進程,最好調整該值,可以一定程度上降低到後端 Shard 的連接數量。
修改 TaskExecutor 的方法如下
1. 啟動命令行指定
mongos --setParameter taskExecutorPoolSize=16
2. 配置文件指定
setParameter:
taskExecutorPoolSize: 16
如果 Client 訪問 Mongos 的並發特別高,修改 TaskExecutor 也無法有效的控製 Mongos 到 Shard 的連接數,因為一旦沒有了空閑的連接,就會創建新的。目前 Mongos 到 Shard 最大連接數還不支持配置,如果確實有需要,可以修改源碼。
src/mongo/executor/connection_pool.h
- size_t maxConnections = std::numeric_limits<size_t>::max();
+ size_t maxConnections = 10000;
最後更新:2017-04-01 17:13:51