sharding是一種將海量數據水平擴展的集群系統,數據分表存儲在sharding的各個節點上,使用者通過簡單的配置就可以很方便地構建一個分布式mongodb集群. sharding不是某個特定數據庫軟件附屬的功能,而是具體技術細節上的抽象處理,是水平擴展(橫向擴展或向外擴展)的解決方案,主要目的是突破單個數據庫服務的I/O能力限制,最終解決數據庫擴展性問題.sharding也有其不適合的場景,比如處理事務的應用就會非常復雜.對於跨DB的事務來說,很難保證完整性.
數據庫sharding主要有以下優點:
提高了近似線性擴展的架構,可以隨着應用的增長線性地增加更多的服務器
提高了數據庫的可用性。如果只有一個數據庫,一旦當掉,對其提供的service影響是100%,如果拆成10台那么,每台當掉的影響就為10%
小型數據庫的壓力比較小,風險小,性能更好.
MongoDB將數據分塊稱為chunk,每個chunk都是collection中一段連續的數據記錄,通常最大尺寸是200MB,超出則生成新的數據塊.
MongoDB的Sharding架構
構建一個mongoDB Sharding Cluster需要三種角色:shard服務器(Shard Server)、配置服務器(config Server)、路由進程(Route Process)
Shard服務器
shard服務器即存儲實際數據的分片,每個shard可以是一個mongod實例,也可以是一組mongod實例構成的Replica Sets.為了實現每個Shard內部的故障自動轉換,MongoDB官方建議每個shard為一組Replica Sets.
配置服務器
為了將一個特定的collection存儲在多個shard中,需要為該collection指定一個shard key,決定該條記錄屬於哪個chunk.配置服務器可以存儲以下信息.
每個shard節點的配置信息
每個chunk的shard key范圍
chunk在各shard的分布情況
集群中所有DB和collection的sharding配置信息.
路由進程
它是一個前段路由,客戶端由此接入,首先詢問配置服務器需要到哪個shard上查詢或保存記錄,然后連接相應的shard執行操作,最后將結果返回給客戶端,客戶端只需要將原本發給mongod的查詢或更新請求原封不動地發給路由進程,而不必關心所操作的記錄存儲在哪個shard上.
構建一個簡單的Sharding Cluster
復制集是由一系列物理機器組成的,用一個機器作為主庫,其他的機器作為從庫,為了演示方便,在同一台物理機器上構建一個簡單的sharding cluster.包括啟動和配置服務器,路由進程等方法.
創建對應的文件夾
數據存放目錄:
D:\program files\mongo\data\shard\sv0
D:\program files\mongo\data\shard\sv1
D:\program files\mongo\data\shard\config
日志存放目錄:
D:\program files\mongo\logs\shard\sv0.log
D:\program files\mongo\logs\shard\sv1.log
D:\program files\mongo\logs\shard\config.log
D:\program files\mongo\logs\shard\route.log
啟動shardserver[啟動2個窗口]
mongod --shardsvr --port 8888 --dbpath=../data/shard/sv0 --logpath=../logs/shard/sv0.log --directoryperdb
mongod --shardsvr --port 8889 --dbpath=../data/shard/sv1 --logpath=../logs/shard/sv1.log --directoryperdb
如下圖:
另起一個窗口
啟動Config Server(新建窗口)
mongod --configsvr --port 6000 --dbpath=../data/shard/config --logpath=../logs/shard/config.log --directoryperdb
如圖:
啟動RouteProcess(新建窗口)
mongos --port 8000 --configdb localhost:6000 --logpath=../logs/shard/route.log --chunkSize 1
參數說明:
chunkSize用來指定chunk的大小(單位:MB),默認值為200
配置Sharding
使用mongo客戶端登錄路由控制器添加shard節點.
D:\program files\mongo\bin>mongo admin --port 8000 MongoDB shell version: 1.8.1 connecting to: 127.0.0.1:8000/admin > db.runCommand({ addshard:"localhost:8888" }) { "shardAdded" : "shard0000", "ok" : 1 } > db.runCommand({ addshard:"localhost:8889" }) { "shardAdded" : "shard0001", "ok" : 1 } > db.runCommand({ enablesharding:"test" }) { "ok" : 1 } > db.runCommand({ shardcollection:"test.users", key:{ _id:1 }}) { "collectionsharded" : "test.users", "ok" : 1 } > 說明: mongo admin --port 8000 表示連接到路由控制器的admin數據庫. db.runCommand({ addshard:"localhost:8888" }) 表示添加本地端口8888的shard server實例. db.runCommand({ enablesharding:"test" })表示要在test數據庫上執行分片,其中的test代表要分片的數據庫. db.runCommand({ shardcollection:"test.users", key:{ _id:1 }}) 設置要在test數據庫的users表上分片,同時指明shard key是id這一列.
如圖:
至此,一個完整的sharding環境部署完畢.
驗證sharding
循環向test.users表中插入20萬條數據,然后使用命令test.users.stats()查看表的分片情況.
> use test switched to db test > for(var i=1; i<200000; i++) db.users.insert({name:"user"+i, age:i, email:"dennisit@163.com" }) > db.users.stats()
如圖:
新增Shard Server
啟動一個新Shard Server進程,如下面代碼所示.
D:\program files\mongo\data\shard\sv2
mongod --shardsvr --port 8887 --dbpath=../data/shard/sv2 --logpath=../logs/shard/sv2.log
配置新shard server.
D:\program files\mongo\bin>mongo admin --port 8000 MongoDB shell version: 1.8.1 connecting to: 127.0.0.1:8000/admin > db.runCommand({ addshard:"localhost:8887"}) { "shardAdded" : "shard0002", "ok" : 1 }
如圖:
接下來看分片表狀態,以驗證新的shard server已生效.
> use test switched to db test > db.users.stats() { "sharded" : true, "ns" : "test.users", "count" : 599998, "size" : 50399116, "avgObjSize" : 83.99880666268888, "storageSize" : 102398720, "nindexes" : 1, "nchunks" : 42, "shards" : { "shard0000" : { "ns" : "test.users", "count" : 233266, "size" : 19594344, "avgObjSize" : 84, "storageSize" : 47822848, "numExtents" : 9, "nindexes" : 1, "lastExtentSize" : 14495232, "paddingFactor" : 1, "flags" : 1, "totalIndexSize" : 9723904, "indexSizes" : { "_id_" : 9723904 }, "ok" : 1 }, "shard0001" : { "ns" : "test.users", "count" : 230087, "size" : 19327336, "avgObjSize" : 84.00012169309869, "storageSize" : 33327616, "numExtents" : 8, "nindexes" : 1, "lastExtentSize" : 12079360, "paddingFactor" : 1, "flags" : 1, "totalIndexSize" : 9592832, "indexSizes" : { "_id_" : 9592832 }, "ok" : 1 }, "shard0002" : { "ns" : "test.users", "count" : 136645, "size" : 11477436, "avgObjSize" : 83.99455523436643, "storageSize" : 21248256, "numExtents" : 7, "nindexes" : 1, "lastExtentSize" : 10066176, "paddingFactor" : 1, "flags" : 1, "totalIndexSize" : 7684096, "indexSizes" : { "_id_" : 7684096 }, "ok" : 1 } }, "ok" : 1 } >
查看Sharding信息
printShardingStatus()
如圖:
移除Shard Server
移除Shard Server,系統首先會將即將移除的Shard Server上的數據平均分配到其他Shard Server上,然后將這個Shard Server踢下線.
注意:移除Shard Server的操作對客戶端完全是透明的,不影響用戶正常使用,也不需要待機進行.
例如要移除8889端口的shard Server, 需要不停地調用以下命令來觀察這個移除操作執行到哪里了.
db.runCommand({ "removeshard":"localhost:8889" );
移除過程中會出現3種狀態.
狀態一如圖,表示移除的動作是剛剛開始.
狀態二如圖,”ongoing”表示移除已經開始
狀態三如圖,”completed”表示移除完成
使用 printShardingStatus();查看Sharding信息
判斷是否是Sharding
通過執行 db.runCommand({ isdbgrid:1 })命令查看當前實例是否在Sharding環境中.
列出所有Shard Server
轉載請注明出處:[http://www.cnblogs.com/dennisit/archive/2013/02/18/2916159.html]