MongoDB で複数シャードを立ち上げる。
最近MongoDBに取り組んでいます。これは、1台のwindowsマシンで2つのシャードを立ち上げたときのメモです。大量emailデータをMongoDBで管理することを想定しています。
MongoDBのインストール方法は
データディレクトリ作成
コマンドプロンプトから実行します。やり直すときは、ここのディレクトリファイルを削除してしまえばよいです。
mkdir \mongo\data\shard_test1\shard0 mkdir \mongo\data\shard_test1\shard1 mkdir \mongo\data\shard_test1\config
サービス達を起動
これもコマンドプロンプトから実行します。
start \mongo\bin\mongod --shardsvr --dbpath \mongo\data\shard_test1\shard0 --port 27101 start \mongo\bin\mongod --shardsvr --dbpath \mongo\data\shard_test1\shard1 --port 27102 start \mongo\bin\mongod --configsvr --dbpath \mongo\data\shard_test1\config --port 27103 start \mongo\bin\mongos --configdb localhost:27103 --port 27104
mongod はサーバープログラム、mongos はルータープログラムです。
ここまでではmongos(port:27104) は mongod:configsvr(port:27103) を参照しているが、mongod:shardsvr(port:27101), mongod:shardsvr(port:27102)は参照されていません。
mongo コンソール起動
コマンドプロンプトから mongo コンソールを起動します。mongos(port:27104)へ接続します。
\mongo\bin\mongo localhost:27104/admin
シャードの初期状態を確認
mongo コンソールからシャードの状態を確認します。当然ながらなんにもありません。
> db.runCommand( { listshards : 1 } ) { "shards" : [ ], "ok" : 1 } > db.printShardingStatus() --- Sharding Status --- sharding version: { "_id" : 1, "version" : 3 } shards: databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" } >
シャードを登録
mongo コンソールからシャードを追加します。ここでmongod:shardsvr(port:27101), mongod:shardsvr(port:27102) が現れます。
> db.runCommand( { addshard : "localhost:27101" } ) { "shardAdded" : "shard0000", "ok" : 1 } > db.runCommand( { addshard : "localhost:27102" } ) { "shardAdded" : "shard0001", "ok" : 1 }
? maxSize パラメータを試してみたけど、想定どおりに利かなかった。あとでまた試そう。
? allowLocal:true をあとで調べよう。
シャードを確認
mongo コンソールからシャードの状態を確認します。
> db.runCommand( { listshards : 1 } ) { "shards" : [ { "_id" : "shard0000", "host" : "localhost:27101" }, { "_id" : "shard0001", "host" : "localhost:27102" } ], "ok" : 1 } > db.printShardingStatus() --- Sharding Status --- sharding version: { "_id" : 1, "version" : 3 } shards: { "_id" : "shard0000", "host" : "localhost:27101" } { "_id" : "shard0001", "host" : "localhost:27102" } databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" } >
これでシャードが登録されました。
test データベース、emails コレクションをシャード対象にする
シャードを登録したあと、データベース、コレクションをシャード対象します。 Shardingの設定をおさらいしましょう。mongoコンソールから実行。
> db.runCommand( { enablesharding : "test" } ); { "ok" : 1 } > db.runCommand( { shardcollection : "test.emails", key : {id:1} }); { "collectionsharded" : "test.emails", "ok" : 1 } >
んで確認。
> db.printShardingStatus() --- Sharding Status --- sharding version: { "_id" : 1, "version" : 3 } shards: { "_id" : "shard0000", "host" : "localhost:27101" } { "_id" : "shard0001", "host" : "localhost:27102" } databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" } { "_id" : "test", "partitioned" : true, "primary" : "shard0000" } test.emails chunks: { "id" : { $minKey : 1 } } -->> { "id" : { $maxKey : 1 } } on : shard0000 { "t" : 1000, "i" : 0 } >
test.emails がシャーディング対象になっています
データ投入
こんな感じのjavascriptで手軽に大量データを作れるのが素敵。「use test」を忘れずに。mongoコンソールからでもいいですが、rockmongoもいいですよね。
function () { for(i=0;i<100000;i++){db.emails.save({id:i, from:(i%100)+1, to:[(i%100)+2, (i%100)+3, (i%100)+4, (i%100)+5], subject:"subject"+i, body:"body"+i });}; }
投入後のデータ確認
> db.emails.findOne() { "_id" : ObjectId("4d651201ba6e000000019c9b"), "id" : 0, "from" : 1, "to" : [ 2, 3, 4, 5 ], "subject" : "subject0", "body" : "body0" } > db.emails.count() 100000 > db.printShardingStatus() --- Sharding Status --- sharding version: { "_id" : 1, "version" : 3 } shards: { "_id" : "shard0000", "host" : "localhost:27101" } { "_id" : "shard0001", "host" : "localhost:27102" } databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" } { "_id" : "test", "partitioned" : true, "primary" : "shard0000" } test.emails chunks: { "id" : { $minKey : 1 } } -->> { "id" : { $maxKey : 1 } } on : shard0000 { "t" : 1000, "i" : 0 } { "_id" : "local", "partitioned" : false, "primary" : "shard0001" } >
# 32ビット版は2GBまでしかつっこめないことに注意
32-bit-limitations
シャード1(shard0000), シャード2(shard0001)に直接接続しデータ件数を確認すると、シャード1にしかデータが登録されていない状態です。