MongoDBでゆるふわDB体験

第5回 MongoDBのシャーディングを試してみよう

この記事を読むのに必要な時間:およそ 3 分

シャーディングを試してみる(後半)

シャーディングの有効化

それではいよいよシャーディングを有効にして,データを分散させてみましょう。シャーディングを有効にするにはshオブジェクトのenableShardingメソッドにデータベース名を指定します。

mongos> use admin
switched to db admin
mongos> sh.enableSharding("logdb")
{ "ok" : 1 }

次にsh.shardCollectionメソッドでシャード化するコレクションを指定します。第一引数は,(データベース名).(コレクション名)の文字列,第二引数はインデックスを作成するときのハッシュです。

mongos> sh.shardCollection("logdb.logs" , { uid : 1 })
{ "collectionsharded" : "logdb.logs", "ok" : 1 }

シャーディングの状態確認

ここでsh.statusメソッドでシャーディングの状態を表示すると,3つのシャードサーバにそれぞれチャンクができている様子がわかります。

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)
        ・・・

上記の出力では,shard0000のチャンク数が8つ,shard0001のチャンク数が1つ,そしてshard0002のチャンク数が1つとなっています。

このようにチャンクの数が偏っているのは,まだデータが移動中であるためです。しばらくした後に,もう一度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       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)

しばらく時間がたつと,チャンクの数が3,3,4と均等になっていることがわかります図4参照⁠⁠。

図4 チャンクの数が均等になったイメージ図

図4 チャンクの数が均等になったイメージ図

データ数やチャンク数はイメージです。

また,出力の後半に各チャンクに入っているシャードキーの範囲が出力されています。

   { "uid" : 10083 } -->> { "uid" : 20166 } on : shard0002 Timestamp(3000, 0)

上記の例では,shard0002のチャンクには,uidの範囲が10083≦uid<20166であるコレクションが格納されていることがわかります。

[参考]$minKeyはすべての値よりも小さいとみなされ,$maxKeyはすべての値よりも大きいとみなされます。

また,別の確認方法として,mongosサーバのconfigテーブルを見る方法もあります。

mongos> use config
switched to db config
mongos> db.chunks.count()
10
mongos> db.chunks.findOne()

各シャードサーバの状態確認

シャーディングされている状態で,各シャードサーバがどのようになっているか確認しましょう。やり方は簡単で,各シャードサーバにmongoシェルで接続すればOKです。まずnode1にアクセスしてみましょう。

$ bin/mongo localhost:30000/logdb
> db.logs.count()
39503
> exit

このように,各シャードサーバに入っているコレクションの数を参照することができます。また,findメソッドなどで普通にコレクションを参照することもできます。他のシャードサーバでも同じです。

$ bin/mongo localhost:30001/logdb
> db.logs.count()
30248
> exit

$ bin/mongo localhost:30002/logdb
> db.logs.count()
30249
> exit

次回のテーマ

今回はMongoDBのデータ分散機能であるシャーディングについて紹介しました。シャーディング機能を使用することにより,負荷分散とリソース分散によるコスト削減を実現できます。また,自動バランシングというMongoDBの特徴的な機能も紹介しました。

次回は,前回の記事で紹介したレプリケーションと今回紹介したシャーディングを組み合わせた構成を紹介します。

著者プロフィール

藤崎祥見(ふじさきしょうけん)

野村総合研究所 OpenStandia所属。オープンソースのR&Dとセミナー講師を担当。

Debian,Ubuntu,Liferayのコミュニティで活動した後,MongoDBの翻訳に関わり,丸の内MongoDB勉強会を始める。

実家がお寺で,住職の資格を所持する坊主系エンジニア。

Twitter:@syokenz


渡部徹太郎(わたなべてつたろう)

野村総合研究所 OpenStandia所属。オープンソースを使ったSIやサポートの業務に従事。

藤崎と共同で丸の内MongoDB勉強会を始める。

趣味は自宅サーバ。好きなものはLinuxとRuby。

Twitter:@fetarodc


林田敦(はやしだあつし)

野村総合研究所 OpenStandia所属。オープンソースを使ったSIや製品開発業務に従事。

丸の内MongoDB勉強会では広報兼雑用係を務める。

趣味はレザークラフト,ダイビング,スキー,キャンプ,ジェットスキー,カメラ等々。作って滑って撮って潜れるエンジニア。

Facebook:Atsushi Hayashida