MongoDB分片集群(Sharded Cluster)通過將數據分散存儲到多個分片(Shard)上,來實現高可擴展性。實現分片集群時,MongoDB 引入 Config Server 來存儲集群的元數據,引入 mongos 作為應用訪問的入口,mongos 從 Config Server 讀取路由信息,並將請求路由到后端對應的 Shard 上。
使用分片集群時你需要知道的
- 用戶訪問 mongos 跟訪問單個 mongod 類似
- 所有 mongos 是對等關系,用戶訪問分片集群可通過任意一個或多個mongos
- mongos 本身是無狀態的,可任意擴展,集群的服務能力為『Shard服務能力之和』與『mongos服務能力之和』的最小值。
- 訪問分片集群時,最好將應用負載均勻的分散到多個 mongos 上
正確連接分片集群的姿勢
要正確連接復制集,需要先了解下MongoDB的Connection String URI,所有官方的driver都支持以 Connection String 的方式來連接 MongoDB 分片集群。
下面就是Connection String包含的主要內容
mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
- mongodb:// 前綴,代表這是一個Connection String
- username:password@ 如果啟用了鑒權,需要指定用戶密碼
- hostX:portX 多個 mongos 的地址列表
- /database 鑒權時,用戶帳號所屬的數據庫
- ?options 指定額外的連接選項
以連接阿里雲數據庫MongoDB版為例,當你購買阿里雲MongoDB分片集群后,就會在控制台上看到各個mongos的地址信息。
為了方便用戶使用,控制台上也生成了連接復制集的Connection String及通過Mongo Shell連接的命令。
例如通過java來連接,更多的DEMO
MongoClientURI connectionString = new MongoClientURI("mongodb://:****@s-m5e80a9241323604.mongodb.rds.aliyuncs.com:3717,s-m5e053215007f404.mongodb.rds.aliyuncs.com:3717/admin"); // ****替換為root密碼 MongoClient client = new MongoClient(connectionString); MongoDatabase database = client.getDatabase("mydb"); MongoCollection<Document> collection = database.getCollection("mycoll");
通過上述方式連接分片集群時,客戶端會自動將請求分散到多個mongos 上,以實現負載均衡;同時,當URI 里 mongos 數量在2個及以上時,當有mongos故障時,客戶端能自動進行 failover,將請求都分散到狀態正常的 mongos 上。
當 Mongos 數量很多時,還可以按應用來將 mongos 進行分組,比如有2個應用A、B、有4個mongos,可以讓應用A 訪問 mongos 1-2(URI里只指定mongos 1-2 的地址), 應用B 來訪問 mongos 3-4(URI里只指定mongos 3-4 的地址),根據這種方法來實現應用間的訪問隔離(應用訪問的mongos彼此隔離,但后端 Shard 仍然是共享的)。
總而言之,在訪問分片集群時,請務必確保 MongoDB URI 里包含2個及以上的mongos地址,來實現負載均衡及高可用。
常用連接參數
如何實現讀寫分離?
在options里添加readPreference=secondaryPreferred即可實現,讀請求優先到Secondary節點,從而實現讀寫分離的功能,更多讀選項參考Read preferences
如何限制連接數?
在options里添加maxPoolSize=xx即可將客戶端連接池限制在xx以內。
如何保證數據寫入到大多數節點后才返回?
在options里添加w= majority即可保證寫請求成功寫入大多數節點才向客戶端確認,更多寫選項參考Write Concern




