MongoDB: 8. Sharding (1)
來源:程序員人生 發布時間:2013-10-21 19:19:30 閱讀次數:2671次
將海量的數據水平或垂直切割,分區存儲到多臺服務器上是一個最基本的現實需求。從 1.6 版開始,MongoDB Sharding 總算打上了 "production-ready" 標記。
MongoDB 的數據分塊稱為 chunk。每個 chunk 都是 Collection 中一段連續的數據記錄,通常最大尺寸是 200MB,超出則生成新的數據塊。
要構建一個 MongoDB Sharding Cluster,需要三種角色:
Shard Server: mongod 實例,用于存儲實際的數據塊。
Config Server: mongod 實例,存儲了整個 Cluster Metadata,其中包括 chunk 信息。
Route Server: mongos 實例,前端路由,客戶端由此接入,且讓整個集群看上去像單一進程數據庫。
Route 轉發請求到實際的目標服務進程,并將多個結果合并回傳給客戶端。Route 本身并不存儲任何數據和狀態,僅在啟動時從 Config Server 獲取信息。Config Server 上的任何變動都會傳遞給所有的 Route Process。
在實際使用中,為了獲取高可用、高性能的集群方案,我們會將 Shard Server 和 Config Server 部署成 Replica Sets,然后用 LVS 部署多個 Route。
我們先構建一個簡單的 Sharding Cluster,以熟悉相關的配置。
(1) 啟動 Shard Server。
$ sudo mkdir -p /var/mongodb/0
$ sudo mkdir -p /var/mongodb/1
$ sudo ./mongod --shardsvr --port 10000 --dbpath /var/mongodb/0 --fork --logpath /dev/null
forked process: 1414
all output going to: /dev/null
$ sudo ./mongod --shardsvr --port 10001 --dbpath /var/mongodb/1 --fork --logpath /dev/null
forked process: 1424
all output going to: /dev/null
(2) 啟動 Config Server。
$ sudo mkdir -p /var/mongodb/config
$ sudo ./mongod --configsvr --port 20000 --dbpath /var/mongodb/config --fork --logpath /dev/null
forked process: 1434
all output going to: /dev/null
(3) 啟動 Route Process。
$ sudo ./mongos --configdb localhost:20000 --fork --logpath /dev/null
forked process: 1443
all output going to: /dev/null
可以用 --chunkSize 參數指定分塊大小。
(4) 連接到 Route,開始配置。
$ ./mongo
MongoDB shell version: 1.6.1
connecting to: test
> use admin
switched to db admin
> db.runCommand({ addshard:"localhost:10000" })
{ "shardAdded" : "shard0000", "ok" : 1 }
> db.runCommand({ addshard:"localhost:10001" })
{ "shardAdded" : "shard0001", "ok" : 1 }
> db.runCommand({ enablesharding:"test" })
{ "ok" : 1 }
> db.runCommand({ shardcollection: "test.users", key: { _id:1 }})
{ "collectionsharded" : "test.users", "ok" : 1 }
addshard: 添加 Shard Server,相關的命令還有 listshards 和 removeshard。
enablesharding: 用于設置可以被分布存儲的數據庫。
shardcollection: 用于設置具體被切塊的集合名稱,且必須指定 Shard Key,系統會自動創建索引。
注: Sharded Collection 只能有一個 unique index,且必須是 shard key。
(5) 相關的管理命令。
listshards 命令列出所有的 Shard Server。
> db.runCommand({ listshards: 1 })
{
"shards" : [
{
"_id" : "shard0000",
"host" : "localhost:10000"
},
{
"_id" : "shard0001",
"host" : "localhost:10001"
}
],
"ok" : 1
}
或用 printShardingStatus 命令查看 Sharding 信息。
> printShardingStatus()
--- Sharding Status ---
sharding version: { "_id" : 1, "version" : 3 }
shards:
{ "_id" : "shard0000", "host" : "localhost:10000" }
{ "_id" : "shard0001", "host" : "localhost:10001" }
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "test", "partitioned" : true, "primary" : "shard0000" }
test.users chunks:
{ "_id" : { $minKey : 1 } } -->> { "_id" : { $maxKey : 1 } }
on : shard0000 { "t" : 1000, "i" : 0 }
isdbgrid 用來確認當前是否是 Sharding Cluster。
> db.runCommand({ isdbgrid:1 })
{ "isdbgrid" : 1, "hostname" : "yuhen-server64", "ok" : 1 }
> db.runCommand({ ismaster:1 })
{ "ismaster" : 1, "msg" : "isdbgrid", "ok" : 1 }
--------- 華麗的分隔線 --------------
測試一下效果:
$ ipython
In [1]: from pymongo import *
In [2]: conn = Connection()
In [3]: db = conn.test
In [4]: for i in xrange(2000000):
...: u = dict(name = "user" + str(i))
...: print i, db.users.insert(u)
# 呼啦啦,好多東東啊,喝茶去...
In [5]: db.users.count()
Out[5]: 2000000
從 test.users chunks 可以看到分塊存儲的范圍。
> printShardingStatus()
--- Sharding Status ---
sharding version: { "_id" : 1, "version" : 3 }
shards:
{ "_id" : "shard0000", "host" : "localhost:10000" }
{ "_id" : "shard0001", "host" : "localhost:10001" }
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "test", "partitioned" : true, "primary" : "shard0000" }
test.users chunks:
{ "_id" : { $minKey : 1 } } -->> { "_id" : ObjectId("4c7...000") }
on : shard0001 { "t" : 2000, "i" : 0 }
{ "_id" : ObjectId("4c7...000") } -->> { "_id" : ObjectId("4c7...d3b") }
on : shard0000 { "t" : 3000, "i" : 1 }
{ "_id" : ObjectId("4c7...d3b") } -->> { "_id" : { $maxKey : 1 } }
on : shard0001 { "t" : 3000, "i" : 0 }
看看存儲目錄使用情況 (刪除了一些信息,便于閱讀)。
$ du -h /var/mongodb | grep -v _tmp
1.2G /var/mongodb
465M /var/mongodb/0
465M /var/mongodb/1
209M /var/mongodb/config
更詳細一些 (刪除了一些信息,便于閱讀)。
$ ls -lhR /var/mongodb
/var/mongodb:
total 12K
drwxr-xr-x 4 root root 4.0K 2010-08-23 19:21 0
drwxr-xr-x 3 root root 4.0K 2010-08-23 19:23 1
drwxr-xr-x 3 root root 4.0K 2010-08-23 18:33 config
/var/mongodb/0:
total 465M
-rwxr-xr-x 1 root root 5 2010-08-23 18:32 mongod.lock
drwxr-xr-x 3 root root 4.0K 2010-08-23 19:21 moveChunk
-rw------- 1 root root 64M 2010-08-23 19:21 test.0
-rw------- 1 root root 128M 2010-08-23 19:21 test.1
-rw------- 1 root root 256M 2010-08-23 19:14 test.2
-rw------- 1 root root 16M 2010-08-23 19:21 test.ns
drwxr-xr-x 2 root root 4.0K 2010-08-23 18:36 _tmp
/var/mongodb/1:
total 465M
-rwxr-xr-x 1 root root 5 2010-08-23 18:32 mongod.lock
-rw------- 1 root root 64M 2010-08-23 19:25 test.0
-rw------- 1 root root 128M 2010-08-23 19:25 test.1
-rw------- 1 root root 256M 2010-08-23 19:23 test.2
-rw------- 1 root root 16M 2010-08-23 19:25 test.ns
drwxr-xr-x 2 root root 4.0K 2010-08-23 19:21 _tmp
/var/mongodb/config:
total 209M
-rw------- 1 root root 64M 2010-08-23 19:26 config.0
-rw------- 1 root root 128M 2010-08-23 18:33 config.1
-rw------- 1 root root 16M 2010-08-23 19:21 config.ns
-rw-r--r-- 1 root root 41K 2010-08-23 19:22 diaglog.4c724e45
-rwxr-xr-x 1 root root 5 2010-08-23 18:32 mongod.lock
drwxr-xr-x 2 root root 4.0K 2010-08-23 18:36 _tmp
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈