MongoDB分片 在部署和維護管理 中常見事項的總結
分片(sharding ) 是MongoDB將大型集合分割到不同伺服器(或者說叢集)上所採用的方法,主要為應對高吞吐量與大資料量的應用場景提供了方法。
和既有的分庫分表、分割槽方案相比,MongoDB的最大區別在於它幾乎能自動完成所有事情,只要告訴MongoDB要分配資料,它就能自動維護資料在不同伺服器之間的均衡。
一. 分片的叢集元件
1.Mongos 【路由】
作為請求的訪問入口,所有的請求都由mongos來路由、分發、合併,這些動作對客戶端driver透明,使用者連線mongos就像連線mongod一樣使用。Mongos會根據請求型別及shard key將請求路由到對應的Shard。
2.Config Server 【配置伺服器】
儲存Sharding Cluster 的所有元資料,所有的元資料都儲存在config資料庫;
*儲存每個分片上的chunk的資訊 * 儲存chunk上的片鍵範圍。
3. Shard 【分片】
儲存應用資料記錄。
二. 分片優勢
1.對叢集進行抽象,讓叢集“不可見”,分片對應用系統是透明的。
Mongos是專有路由程序,其會將客戶端發來的請求準確無誤的路由到叢集中的一個或者一組伺服器上,同時會把接收到的響應拼裝起來發回到客戶端。
2.保證叢集總是可讀寫
將MongoDB的分片和複製集功能結合使用,在確保資料分片到多臺伺服器的同時,也確保了每分資料都有相應的備份,可以確保有伺服器壞掉時,其他的從庫可以立即接替壞掉的部分繼續工作。提高了叢集的可用性和可靠性。
3.使叢集易於擴充套件
當系統需要更多的空間和資源的時候,MongoDB使我們可以按需方便的擴充系統容量。
三. 分片部署注意事項(常見錯誤)
1.配置可複製集作為分片節點與配置單獨使用的可複製集基本一樣。但啟動引數中需指定—shardsvr引數。
否則,在啟動資料庫分片時報錯: {"code" : 193,"ok" : 0, "errmsg" : "Cannot accept sharding commands if not started with --shardsvr“}。
2.建立配置伺服器叢集時,不能設定見證節點。
否則,報錯 "errmsg" : "Arbiters are not allowed in replica set configurations being used for config servers"。
3.配置Mongos 例項時,請不要配置dbpath引數。
否則,設定dbpath引數,服務無法正常啟動,報錯: Error parsing INI config file: unrecognised option 'dbpath'。
4.配置Mongos 例項時,需設定Keyfile。
否則,不設定Keyfile,Service無法正常啟動, 報錯:2018-05-10T15:30:26.791+0800 W SHARDING [mongosMain] Error initializing sharding state, sleeping for 2 seconds and trying again :: caused by :: Unauthorized: Error loading clusterID :: caused by :: not authorized on config to execute command { find: “version”, readConcern: { level: “majority”, afterOpTime: { ts: Timestamp 1525937413000|2, t: 1 } }, maxTimeMS: 30000
5.分片集合設定。
分片不會預設生成,需要先在資料庫中啟動分片(sh.enableSharding(“DBName”)),然後再設定集合分片(sh.shardCollection(“Collection”{片鍵}))
四. 分片管理的注意事項(常用命令)
1.檢查shards 配置及狀態
db.runCommand({listshards:1})
2. 檢查資料庫主片的地址以及是否分割槽
db.getSiblingDB("config").databases.find()
3. 檢查資料塊的數量
db.chunks.count() -- 需切換到配置資料庫(config )
4. 檢視分片的詳細資訊,包括資料庫資訊和範圍資訊
sh.status()
5. 索引是優化查詢效能的重要手段。當在分片集合上宣告索引時,每個分片都會為自己的集合部分定義單獨的索引。分片集合只允許在_id欄位和分片鍵上建立唯一索引。
6. 分割和遷移 MongoDB底層依賴2個機制來保持叢集的平衡:分割和遷移。
分割是把一個大的資料塊分割為2個更小的資料塊的過程。遷移就是在分片之間移動資料塊的過程。當某些分片伺服器包含的資料塊資料量大大超過其他分片伺服器時就會觸發遷移的過程,這個觸發器叫做遷移回合(migration round)
6.1 遷移觸發條件
6.2 檢視Balancer 程序是否開啟 sh.getBalancerState()
6.3 停Balancer 程序 sh.stopBalancer() 和 開啟Balancer 程序
6.4. 預設情況下 Balancer 程序一直在執行,為了降低Balancer程序對系統的執行,可以為Balancer程序設定執行時間視窗,讓Balancer程序在指定的時間視窗操作。
6.4.1 例如設定Balancer程序在23:00到6:00時間視窗內執行。 db.settings.update({ _id : "balancer" }, { $set : { activeWindow : { start : "23:00", stop : "6:00" } } }, true ) ;
6.4.2 刪除Balancer程序執行時間視窗
6.5. 檢視塊的範圍
6.5.1 如果集合資料量較小,可以直接通過sh.status()檢視
6.5.2 如果集合資料量較大,sh.status()無法反應此集合的分塊資訊。此時,可通過執行以下命令檢視printShardingStatus(db.getSisterDB("config"),1);
6.5.3 也可將命令切換到config資料庫下,執行db.chunks.find()檢視。可以輸入制定引數,例如,檢視分片repsms2,集合cloud-docs.PushMessageRecord的塊情況(cloud-docs為資料庫名稱)
db.chunks.find({"shard" : "repsms2","ns" : "cloud-docs.PushMessageRecord"}).pretty()
五. 備註
分片叢集管理的資料量比較大,並且分片的架構相對比較複雜。所以,一定在業務需求需要上分片時,再上分片,且不可準求“炫”的技術而上分片。另外,上線後,相關的監控一定要部署,逐漸完善。