Sharding 環境を構築する事でデータを効果的に分散させて保持し、パフォーマンスの向上を狙う。MongoDB の Sharding では分割用のキーを指定する事でデータが分散して登録される。今回は下記4つの項目を持つログを登録するが、その中で Sharding 用のキーとして {ym, account_id} の2項目を用いる事とする。
登録ドキュメント形式
| id | ID |
| uid | ユーザID |
| ymd | 年月 |
| timestamp | yyyy-mm-dd hh:mm:ss |
今回の目標: 3ノードによる Sharding 環境を構築し、データを分散登録する。
上記の構成図にあるようにユーザは Sharding 用のデータ取りまとめノードである mongos のみとデータのやりとりを行い、 mongos が config ノードや mongod01/mongod02 とやり取りする事でユーザにあたかも1台の DB だけとやり取りを行っているように見せる事が可能となる。
サーバを起動
$ mongod --shardsvr --port 10001 --dbpath data/shrd11 // mongod01 $ mongod --shardsvr --port 10002 --dbpath data/shrd12 // mongod02 $ mongod --configsvr --port 10010 --dbpath data/config // config $ mongos --configdb localhost:10010 --port 10000 // mongos: config サーバを指定
mongos へ接続し Sharding 環境を設定
$ mongo localhost:10000
MongoDB shell version: 2.0.2
connecting to: localhost:10000/test
mongos>
// Shard を追加
mongos> use admin
mongos> db.runCommand({addshard: 'localhost:10001'});
{ "shardAdded" : "shard0000", "ok" : 1 }
mongos> db.runCommand({addshard: 'localhost:10002'});
{ "shardAdded" : "shard0001", "ok" : 1 }
// 登録済 Shard の確認
mongos> db.runCommand({listshards: 1});
{
"shards" : [
{
"_id" : "shard0000",
"host" : "localhost:10001"
},
{
"_id" : "shard0001",
"host" : "localhost:10002"
}
],
"ok" : 1
}
// Sharding 対象 DB を指定
mongos> db.runCommand({enablesharding: 'testdb'});
{ "ok" : 1 }
// Sharding 対象 Collection を指定
mongos> db.runCommand({shardcollection: 'testdb.logs', key: {ymd: 1, uid: 1}});
{ "collectionsharded" : "testdb.logs", "ok" : 1 }
// Sharding の状態を確認
mongos> db.printShardingStatus();
--- Sharding Status ---
sharding version: { "_id" : 1, "version" : 3 }
shards:
{ "_id" : "shard0000", "host" : "localhost:10001" }
{ "_id" : "shard0001", "host" : "localhost:10002" }
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "testdb", "partitioned" : true, "primary" : "shard0000" } // primary shard = localhost:10001
testdb.logs chunks:
shard0000 1
{ "ymd" : { $minKey : 1 }, "uid" : { $minKey : 1 } } -->> { "ymd" : { $maxKey : 1 }, "uid" : { $maxKey : 1 } } on : shard0000 { "t" : 1000, "i" : 0 }
お試しデータを登録してみる事にする。
mongos> use testdb
switched to db testdb
mongos> show collections
logs
system.indexes
mongos> db.logs.insert({ymd: 20120128, uid: 12345});
primary shard(localhost:10001) を確認
*デフォルトでは200MBを境に Sharding が実施されるが、それまでは primary shard へデータが登録され続ける
$ mongo localhost:10001
MongoDB shell version: 2.0.2
connecting to: localhost:10001/test
> show dbs
admin (empty)
local (empty)
testdb 0.203125GB
> use testdb
switched to db testdb
> show collections
logs // ちゃんとある!!
system.indexes
// ちゃんとデータが存在する事を確認
> db.logs.find()
{ "_id" : ObjectId("4f22cf875901ed90a81dbb16"), "ymd" : 20120128, "uid" : 12345 }
// お試しデータなのでちゃんと消しておく
> db.logs.remove()
> db.logs.findOne();
null
次に約300万件のログを mongoimport コマンドで登録してみる。
$ time mongoimport -h localhost:10000 -d testdb -c logs --type csv --headerline --ignoreBlanks --file export_log_data.csv connected to: localhost:10000 325564/134551732 0% 8400 1680/second 846166/134551732 0% 21300 2662/second 1500937/134551732 1% 37400 3400/second 2352237/134551732 1% 58300 4164/second インポート中…
途中経過を mongos で確認
// shard0000(=localhost:10001)に5つ、shard0001(=localhost:10002)に4つの Chunk(データの分割単位) が存在する事が分かる
mongos> db.printShardingStatus();
--- Sharding Status ---
sharding version: { "_id" : 1, "version" : 3 }
shards:
{ "_id" : "shard0000", "host" : "localhost:10001" }
{ "_id" : "shard0001", "host" : "localhost:10002" }
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "testdb", "partitioned" : true, "primary" : "shard0000" }
testdb.logs chunks:
shard0000 5 // localhost:10001 の chunk 数
shard0001 4 // localhost:10002 の chunk 数
{ "ymd" : { $minKey : 1 }, "uid" : { $minKey : 1 } } -->> { "ymd" : NumberLong(20110318), "uid" : 100 } on : shard0000 { "t" : 2000, "i" : 1 }
{ "ymd" : NumberLong(20110318), "uid" : 100 } -->> { "ymd" : NumberLong(20110319), "uid" : 6854 } on : shard0000 { "t" : 1000, "i" : 3 }
{ "ymd" : NumberLong(20110319), "uid" : 6854 } -->> { "ymd" : NumberLong(20110327), "uid" : 35690 } on : shard0001 { "t" : 3000, "i" : 1 }
{ "ymd" : NumberLong(20110327), "uid" : 35690 } -->> { "ymd" : NumberLong(20110403), "uid" : 62791 } on : shard0001 { "t" : 2000, "i" : 5 }
{ "ymd" : NumberLong(20110403), "uid" : 62791 } -->> { "ymd" : NumberLong(20110409), "uid" : 17526 } on : shard0001 { "t" : 3000, "i" : 2 }
{ "ymd" : NumberLong(20110409), "uid" : 17526 } -->> { "ymd" : NumberLong(20110417), "uid" : 78041 } on : shard0001 { "t" : 3000, "i" : 3 }
{ "ymd" : NumberLong(20110417), "uid" : 78041 } -->> { "ymd" : NumberLong(20110425), "uid" : 6578 } on : shard0000 { "t" : 3000, "i" : 6 }
{ "ymd" : NumberLong(20110425), "uid" : 6578 } -->> { "ymd" : NumberLong(20110504), "uid" : 84974 } on : shard0000 { "t" : 3000, "i" : 7 }
{ "ymd" : NumberLong(20110504), "uid" : 84974 } -->> { "ymd" : { $maxKey : 1 }, "uid" : { $maxKey : 1 } } on : shard0000 { "t" : 3000, "i" : 5 }
{ "_id" : "test", "partitioned" : false, "primary" : "shard0001" }
終わったようなのでデータを確認
133092317/134551732 98%
3101300 6771/second
133821849/134551732 99%
3118000 6763/second
134390051/134551732 99%
3131000 6747/second
imported 3134701 objects // ヘッダ行を含むのでデータは 3134700 レコード
mongos> db.printShardingStatus();
--- Sharding Status ---
sharding version: { "_id" : 1, "version" : 3 }
shards:
{ "_id" : "shard0000", "host" : "localhost:10001" }
{ "_id" : "shard0001", "host" : "localhost:10002" }
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "testdb", "partitioned" : true, "primary" : "shard0000" }
testdb.logs chunks:
shard0000 7
shard0001 11
{ "ymd" : { $minKey : 1 }, "uid" : { $minKey : 1 } } -->> { "ymd" : NumberLong(20110318), "uid" : 100 } on : shard0000 { "t" : 4000, "i" : 1 }
{ "ymd" : NumberLong(20110318), "uid" : 100 } -->> { "ymd" : NumberLong(20110319), "uid" : 6854 } on : shard0000 { "t" : 1000, "i" : 3 }
{ "ymd" : NumberLong(20110319), "uid" : 6854 } -->> { "ymd" : NumberLong(20110327), "uid" : 35690 } on : shard0001 { "t" : 5000, "i" : 1 }
{ "ymd" : NumberLong(20110327), "uid" : 35690 } -->> { "ymd" : NumberLong(20110403), "uid" : 62791 } on : shard0001 { "t" : 2000, "i" : 5 }
{ "ymd" : NumberLong(20110403), "uid" : 62791 } -->> { "ymd" : NumberLong(20110409), "uid" : 17526 } on : shard0001 { "t" : 3000, "i" : 2 }
{ "ymd" : NumberLong(20110409), "uid" : 17526 } -->> { "ymd" : NumberLong(20110417), "uid" : 78041 } on : shard0001 { "t" : 3000, "i" : 3 }
{ "ymd" : NumberLong(20110417), "uid" : 78041 } -->> { "ymd" : NumberLong(20110425), "uid" : 6578 } on : shard0000 { "t" : 3000, "i" : 6 }
{ "ymd" : NumberLong(20110425), "uid" : 6578 } -->> { "ymd" : NumberLong(20110504), "uid" : 84974 } on : shard0000 { "t" : 3000, "i" : 7 }
{ "ymd" : NumberLong(20110504), "uid" : 84974 } -->> { "ymd" : NumberLong(20110519), "uid" : 103548 } on : shard0000 { "t" : 3000, "i" : 8 }
{ "ymd" : NumberLong(20110519), "uid" : 103548 } -->> { "ymd" : NumberLong(20110614), "uid" : 134231 } on : shard0000 { "t" : 3000, "i" : 10 }
{ "ymd" : NumberLong(20110614), "uid" : 134231 } -->> { "ymd" : NumberLong(20110718), "uid" : 141818 } on : shard0001 { "t" : 4000, "i" : 2 }
{ "ymd" : NumberLong(20110718), "uid" : 141818 } -->> { "ymd" : NumberLong(20110806), "uid" : 16293 } on : shard0001 { "t" : 4000, "i" : 6 }
{ "ymd" : NumberLong(20110806), "uid" : 16293 } -->> { "ymd" : NumberLong(20110905), "uid" : 153701 } on : shard0001 { "t" : 4000, "i" : 7 }
{ "ymd" : NumberLong(20110905), "uid" : 153701 } -->> { "ymd" : NumberLong(20110930), "uid" : 141517 } on : shard0001 { "t" : 4000, "i" : 10 }
{ "ymd" : NumberLong(20110930), "uid" : 141517 } -->> { "ymd" : NumberLong(20111104), "uid" : 165311 } on : shard0001 { "t" : 4000, "i" : 11 }
{ "ymd" : NumberLong(20111104), "uid" : 165311 } -->> { "ymd" : NumberLong(20111206), "uid" : 132993 } on : shard0001 { "t" : 5000, "i" : 2 }
{ "ymd" : NumberLong(20111206), "uid" : 132993 } -->> { "ymd" : NumberLong(20120117), "uid" : 183726 } on : shard0001 { "t" : 5000, "i" : 3 }
{ "ymd" : NumberLong(20120117), "uid" : 183726 } -->> { "ymd" : { $maxKey : 1 }, "uid" : { $maxKey : 1 } } on : shard0000 { "t" : 5000, "i" : 0 }
{ "_id" : "test", "partitioned" : false, "primary" : "shard0001" }
mongos> use testdb
switched to db testdb
mongos> db.logs.count()
3134700
mongos> db.logs.findOne()
{
"_id" : ObjectId("4f22d4428b618b0098535103"),
"uid" : 100,
"ymd" : NumberLong(20110318),
"id" : 1,
"timestamp" : "2011-03-18 22:02:13"
}
localhost:10001 を確認
$ mongo localhost:10001
MongoDB shell version: 2.0.2
connecting to: localhost:10001/test
> use testdb
switched to db testdb
> db.logs.count()
935965
> db.logs.findOne()
{
"_id" : ObjectId("4f22d4428b618b0098535103"),
"uid" : 100,
"ymd" : NumberLong(20110318),
"id" : 1,
"timestamp" : "2011-03-18 22:02:13"
}
localhost:10002 を確認
$ mongo localhost:10002
MongoDB shell version: 2.0.2
connecting to: localhost:10002/test
> use testdb
switched to db testdb
> db.logs.count()
2198735
> db.logs.findOne()
{
"_id" : ObjectId("4f22d4438b618b0098536b6b"),
"uid" : 6854,
"ymd" : NumberLong(20110319),
"id" : 6760,
"timestamp" : "2011-03-19 19:09:41"
}
935965 + 2198735 = 3134700 でドキュメント数の整合性がちゃんと取れている事が分かる。
最後に mongod01 を停止した上でのデータアクセスについて検証してみる。
mongos からのデータアクセスを検証
mongod02 からのデータアクセスを検証
mongos からのデータアクセスを検証
// mongod01 を停止
^C
// mongos に接続
$ mongo localhost:10000
MongoDB shell version: 2.0.2
connecting to: localhost:10000/test
// エラー発生
mongos> show dbs
Sat Jan 28 02:12:16 uncaught exception: error { "$err" : "socket exception", "code" : 11002 }
mongos> use testdb
switched to db testdb
mongos> show collections
Sat Jan 28 02:12:28 uncaught exception: error: { "$err" : "socket exception", "code" : 11002 }
mongos> db.logs.count()
Sat Jan 28 02:12:43 uncaught exception: error { "$err" : "socket exception", "code" : 11002 }
mongos> db.logs.find()
error: {
"$err" : "could not initialize cursor across all shards because : socket exception @ localhost:10001",
"code" : 14827
}
mongod02 からのデータアクセスを検証
// mongod02 に接続
$ mongo localhost:10002
MongoDB shell version: 2.0.2
connecting to: localhost:10002/test
// こちらはデータアクセス可能
> show dbs
admin (empty)
local (empty)
testdb 1.953125GB
> use testdb
switched to db testdb
> show collections
logs
system.indexes
> db.logs.count()
2198735
> db.logs.findOne()
{
"_id" : ObjectId("4f22d4438b618b0098536b6b"),
"uid" : 6854,
"ymd" : NumberLong(20110319),
"id" : 6760,
"timestamp" : "2011-03-19 19:09:41"
}
今回は Sharding 環境の構築を行った。
次回は ReplicaSet+Sharding で『可用性の確保+データの分散保持』を行ってみる。

0 件のコメント:
コメントを投稿