はじめに
今回は、
シャーディングとは、
シャーディングはMongoDBの機能の中でも重要かつ複雑なもののひとつです。手元の環境で構築することが、
シャーディングのメリット
シャーディングはMongoDBを水平スケーリングさせる機能で、
負荷分散による性能の向上
データを複数のサーバに分散させることにより、
リソース分散によるコストパフォーマンスの向上
近年、
メモリを例にあげますと、
MongoDBのシャーディングの概要
シャーディングについて、
シャードキーのレンジ(範囲)によるデータ分散
MongoDBのシャーディングはレンジパーティション方式を採用しています
シャーディングのイメージを図で表すと、

自動バランシング
キー範囲の調整と、
重要キーワードの説明
シャーディングに登場するキーワードに関して説明します。
シャード
実際にデータが格納されているmongodプロセスです。1つのドキュメントは1つのシャードに格納され、
configサーバ
シャーディングのメタデータを管理しているmongodプロセスです。単一障害点となるので、
mongosサーバ
シャーディングにおけるルーティングプロセスです。シャードとクライアントを連携させます。必要があれば複数のmongosサーバをたてることが可能です。mongodプロセスではないので、
シャードキー
データを分散する範囲のキーです。複数指定もできます。キー上のどの範囲のデータがどのシャードに格納されるかは、
チャンク
シャーディングにおけるチャンクとは、
これまでに説明したキーワードは、
シャーディングを試してみる(前半)
このページと次のページでは、
今回は、

システムを構成するサーバの準備
ディレクトリ作成
まずデータディレクトリとログディレクトリを作成します。手順はすべてMongoDBを展開したディレクトリで行うことを想定しています。
$ cd (MongoDBの展開ディレクトリ) $ mkdir -p data/config $ mkdir data/node0 $ mkdir data/node1 $ mkdir data/node2 $ mkdir log
シャードの起動
$ bin/mongod --shardsvr --port 30000 --dbpath data/node0 --logpath log/node0.log --fork $ bin/mongod --shardsvr --port 30001 --dbpath data/node1 --logpath log/node1.log --fork $ bin/mongod --shardsvr --port 30002 --dbpath data/node2 --logpath log/node2.log --fork
mongodコマンドに--shardsvrのオプションを指定することにより、
configサーバ起動
$ bin/mongod --configsvr --port 20001 --dbpath data/config --logpath log/config.log --fork
mongodコマンドに--configsvrのオプションを指定することにより、
mongosサーバ起動
$ bin/mongos --configdb localhost:20001 --port 20000 --logpath log/mongos.log --chunkSize 1 --fork
mongosコマンドによりmongosサーバを起動します
確認
psコマンドで5つのプロセスが見えればOKです。
$ ps -ef | grep mongo root 1221 ・・ bin/mongod --shardsvr --port 30000 --dbpath data/node0 --logpath log/node0.log root 1235 ・・ bin/mongod --shardsvr --port 30001 --dbpath data/node1 --logpath log/node1.log root 1236 ・・ bin/mongod --shardsvr --port 30002 --dbpath data/node2 --logpath log/node2.log root 1239 ・・ bin/mongod --configsvr --port 20001 --dbpath data/config --logpath log/config.log root 1241 ・・ bin/mongos --configdb localhost:20001 --port 20000 --logpath log/mongos.log --chunkSize 1
mongosサーバにシャードの追加
mongoシェルで、
$ bin/mongo localhost:20000/admin
sh.
mongos> sh.addShard("localhost:30000") // ←30000ポートのmongodを追加 { "shardAdded" : "shard0000", "ok" : 1 } // ←okの値が1であれば正常です mongos> sh.addShard("localhost:30001") // ←30001ポートのmongodを追加 { "shardAdded" : "shard0001", "ok" : 1 } // ←okの値が1であれば正常です mongos> sh.addShard("localhost:30002") // ←30002ポートのmongodを追加 { "shardAdded" : "shard0002", "ok" : 1 } // ←okの値が1であれば正常です
「sh」
sh.
mongos> sh.status() --- Sharding Status --- sharding version: { "_id" : 1, "version" : 3 } shards: { "_id" : "shard0000", "host" : "localhost:30000" } // ←3つのmongodが追加されている { "_id" : "shard0001", "host" : "localhost:30001" } { "_id" : "shard0002", "host" : "localhost:30002" } databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" }
データの投入
続いて、
mongosサーバに接続している状態で、
mongos> use logdb switched to db logdb
続いて、
mongos> for(var i=1; i
最後にuidにインデックスを張ります。理由は、
mongos> db.logs.ensureIndex( { uid : 1 } );
この時点ではまだシャーディングは有効になっていません。単純に最初のノードに10万件のデータが入っているだけです

この状態を確認するには、
mongos> use config switched to db config mongos> db.chunks.count() // ←チャンクの数を表示 0 // ←0であることがわかる
シャーディングを試してみる(後半)
シャーディングの有効化
それではいよいよシャーディングを有効にして、
mongos> use admin switched to db admin mongos> sh.enableSharding("logdb") { "ok" : 1 }
次にsh.
mongos> sh.shardCollection("logdb.logs" , { uid : 1 }) { "collectionsharded" : "logdb.logs", "ok" : 1 }
シャーディングの状態確認
ここでsh.
mongos> sh.status() --- Sharding Status --- sharding version: { "_id" : 1, "version" : 3 } shards: { "_id" : "shard0000", "host" : "localhost:30000" } { "_id" : "shard0001", "host" : "localhost:30001" } { "_id" : "shard0002", "host" : "localhost:30002" } databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" } { "_id" : "logdb", "partitioned" : true, "primary" : "shard0000" } logdb.logs chunks: shard0001 1 // ←shard0001のチャンク数 shard0002 1 // ←shard0002のチャンク数 shard0000 8 // ←shard0000のチャンク数 { "uid" : { $minKey : 1 } } -->> { "uid" : 10083 } on : shard0001 Timestamp(2000, 0) { "uid" : 10083 } -->> { "uid" : 20166 } on : shard0002 Timestamp(3000, 0) ・・・
上記の出力では、
このようにチャンクの数が偏っているのは、
--- Sharding Status --- sharding version: { "_id" : 1, "version" : 3 } shards: { "_id" : "shard0000", "host" : "localhost:30000" } { "_id" : "shard0001", "host" : "localhost:30001" } { "_id" : "shard0002", "host" : "localhost:30002" } databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" } { "_id" : "logdb", "partitioned" : true, "primary" : "shard0000" } logdb.logs chunks: shard0001 3 // ←shard0001のチャンク数 shard0002 3 // ←shard0002のチャンク数 shard0000 4 // ←shard0000のチャンク数 { "uid" : { $minKey : 1 } } -->> { "uid" : 10083 } on : shard0001 Timestamp(2000, 0) { "uid" : 10083 } -->> { "uid" : 20166 } on : shard0002 Timestamp(3000, 0)
しばらく時間がたつと、

また、
{ "uid" : 10083 } -->> { "uid" : 20166 } on : shard0002 Timestamp(3000, 0)
上記の例では、
また、
mongos> use config switched to db config mongos> db.chunks.count() 10 mongos> db.chunks.findOne()
各シャードサーバの状態確認
シャーディングされている状態で、
$ bin/mongo localhost:30000/logdb > db.logs.count() 39503 > exit
このように、
$ bin/mongo localhost:30001/logdb > db.logs.count() 30248 > exit $ bin/mongo localhost:30002/logdb > db.logs.count() 30249 > exit
次回のテーマ
今回はMongoDBのデータ分散機能であるシャーディングについて紹介しました。シャーディング機能を使用することにより、
次回は、