閱讀446 返回首頁    go 阿裏雲 go 技術社區[雲棲]


分片集群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 將請求扔給調度器,然後等待任務執行完成。

_2017_03_31_4_01_23

關於 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:失敗的連接,需要釋放

連接池管理規則

  1. 連接池的總連接會控製在[minConnections, maxConnections]之間,默認為1和無窮大
  2. 當需要新建連接時,會發起一個新建連接的異步請求,並把請求放到 processingPool
  3. 當連接建立成功後,會把請求轉移到readyPool,readyPool 裏的連接可以直接用於服務新的請求
  4. 服務某個請求時會從 readyPool 裏取出連接後,會將連接轉移到 checkOutPool,標識為正在使用
  5. 連接使用完後,會歸還到 readyPool
  6. 當遇到請求失敗 或 一個網絡連接空閑超過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

  上一篇:go 3月31日雲棲精選夜讀:數據科學谘詢:想要轉型毫無頭緒?看了本文你不慌
  下一篇:go 性能測試腳本的編寫和調試【雲享團】