Shardingの紹介

based on v56 (2010/12/18 更新) - オリジナル

MongoDB はauto-sharding機能をサポートし、複数のノードでのスケールアウトを容易にします。

シングルデータベースサーバーのリソースが急速に成長するような環境において、Shardingは効果的な適用事例です。MongoDBはもとのアプリケーションコードを書き換えることなく、Shardingされたクラスタの結合を可能にし、ノード間でのフェイルオーバーやバランシングを自動で管理してくれます。

本ドキュメントではMongoDBのauto-sharding機能について、スケーラビリティに関する部分を詳細に説明します。また、スケーラビリティを可能にする各種コンポーネントのアーキテクチャの概要についても触れます。

また、現在のShardingの制限も確認するようにして下さい。

MongoDBのauto-sharding

Shardingの概要

Shardingは順序を保持した特定のルールに従ってデータを複数のマシンに分割します。Shardingの例を考えてみましょう、住人の居住州情報の入ったコレクションのShardingを思い浮かべて下さい。もし3つのマシンをshardサーバーに使用するならば、1つ目のShardにはAlaskaとKansasを含むユーザーを、2つ目にはKentuckyとNew York、3つ目にはNorth CarolinaとWyomingを含むようなsharding構成が簡単に考えられます。

Shardingは元々優れた効果を発揮するような大きいデータ、ここではユーザーの人口がある閾値を超えたときのみにその機能が有効になるようなシンプルなアーキテクチャをもっています。ここではMongo上にデータが大量にあり、私たちはデータを分割し、かつその分割が全てのserverに分散するような状況を扱うことにします。

アプリケーションにおいては mongos プロセスがshard化されたクラスターを互いに接続・結合し、関連するshard上のみ巡回する操作を行います。このようにして、アプリケーション上ではshard化されたMongoDBクラスターでもシングルノードのデータベースのような振る舞いを見せます。しかし実際はリソースが適切に分散配置されていますので、システムのキャパシティの大幅な拡張を実現しています。

もし users collectionの書き込みが増えて高負荷になった場合、それらの書き込み先は3つのサーバーに分散されることになります。検索の際にもクエリはshard上で分散して実行されますので、同じようにその効果を発揮することができます。

ドキュメントは順序を保持した特定のルールによって構成されています。今回の例で言えば特定の居住州に対するあらゆる操作はそれを含むノード上のみを巡回するように最適化されています。

注目すべき点は、Shardingはcollection単位で構成するようになっており、データベース全体をベースにはしていないことです。これはアプリケーションの急成長にともなって、ある特定のcollectionのみが他のcollectionに比べて急激に増大する場合において効果を発揮します。

例えば、Twitterのようなサービスを構築しようとした場合、replyやdirect messageを保持するcollectionよりもtweetを含むcollectionの方が遙かに高いオーダーで増加することが考えられます。このような状況では率先してこのような大きなサイズ・高スループットのcokkectionに対してshardingが行われます。一方で他の小さなcollectionはまだシングルサーバーで構成されます。

MongoDBのshardingアーキテクチャにおいては、shard化されていないcollectionはある1つノードに存在するような形になっています。

バランシングとフェイルオーバー

Shardingアーキテクチャはバランシングとフェイルオーバー機能を必要とします。

バランシングはある特定のノードだけが他のノードに比べてデータが増大し高負荷になった場合に必要です。この状況においては、データは全てのshardに負荷が均等になるように再度分散配置されます。

自動フェイルオーバー機能もまた重要な機能です。システムが適切に機能するためには全てのshard化されたノードが常にオンラインとなっている必要があります。実際このためには、各shardがreplica setとしての役割を果たす1台以上のマシンを含んでいないといけません。

Replica setはn台のサーバーの集合であり、ほとんどの場合は3台以上で構成され、各サーバーは与えられたshardサーバーの上で完全なデータセットの複製を保持しています。Replica Set内のn台のサーバーは常にmasterになる可能性を持っています。

もし現在のReplica setのmasterのがダウンした場合、残りのメンバーが次のmasterを選択することができます。
なので、自動フェイルオーバー機能は個々のshardに対して提供されます。

Replica setは1.5.x開発版においてShardingと並んで重要な機能フォーカスでした。

詳細はReplica Setsを参照して下さい。

スケーリングモデル

MongoDBのauto-shardingスケーリングモデルはYahooのPNUTSとGoogleのBigTableと多くの共通点を持ちます。順序関係不変のパーティショニングを採用する分散データベースの詳細な議論に興味のある方はWhitePaper::PNUTS: Yahoo!’s Hosted Data Serving PlatformBigtable: A Distributed Storage System for Structured Dataを参照して下さい。

アーキテクチャ概要

MongoDBのshardクラスターを構成するためには2つ以上のshard ( mongod インスタンス) 、1つ以上のconfigサーバーとそれにアプリケーションが接続するための mongos ルーティングプロセスが必要です。それらの

Shard

それぞれのshardは1つ以上のサーバで構成され、mongodプロセス (mongodはMongoDBのデータベースプロセスのコアです) を使いデータを保存します。プロダクション環境においては、可用性を高め、自動フェイルオーバー機能を有効にするために1つのshardに対し複数のサーバを用意しそこにReplicationを構築します。この複数のサーバ/mongodプロセスのセットは、 replica set から成ります。

Replica sets は、以前から (SERVER-557) で議論されたMongoDBの新しいバージョンのレプリケーションです。

テストを行う場合は、1つのshardごとに1つの mongod インスタンスを使います。もし冗長性が必要ならば、各shardの mongod masterに対して1つ以上の mongod slaveを作って下さい。Replica Setsが利用可能になるまで、この設定の場合は手動でフェイルオーバーを行う必要があります。

Shardキー

コレクションを分割するために、shardキーのパターンを定義します。このパターンはインデックスの定義で使われるパターンに似ています。1つかまたは2つ以上のフィールドが分散するデータのキーになります。以下はshardキーのいくつかの例です。

{ state : 1 }
{ name : 1 }
{ _id : 1 }
{ lastname : 1, firstname : 1 }
{ tag : 1, timestamp : -1 }

MongoDBは順番を保持します。shardキーによって、近くのデータは同じサーバー(同じchunk)に存在する傾向があります。configデータベースはデータがどのレンジのshardに入るかを特定するためのメタデータを全て保持しています。

Chunks

chunkは、特定のコレクションの連続した範囲のデータ(ドキュメント)です。(コレクション, 最小キー, 最大キー)の組み合わせでchunkを表現できます。shardキーが K のドキュメントは、「最小キー」<= K < 「最大キー」と言う条件のchunkにマッチします。

chunkは、最大サイズ(標準で200MB)に達すると、そのchunkは2つの新しいchunkに 分割 されます。あるshardが余剰データを持っている場合、chunkがシステムによって他のshardに移動されます。同様に、サーバ(shard)を追加したときchunkは移動します。

shardキーを選択する時には、これらのキーのデータが十分に分散される事が保証される 粒度 を持つべきであることに注意して下さい。例えば前述の例ではshardキーは name でした。この場合は特定のnameだけにデータ偏るといった不釣り合いが起こらない様にして下さい、さもないとこの場合ではchunk内に1つのキー値のみを持つchunkが肥大化して分割が不可能な状態に陥ります。

もしある特定のshardキーの値が指数的に大きくなる場合には、そのshardキーで分割をするのではなく、替わりに均等に分布するshardキーを選ぶのが適切な対処になります。

Configサーバー

configサーバは、クラスタのメタデータを保存します。これは、基本的なshardとサーバー、chunkの情報などを含みます。

configサーバーによって保存される主なデータは、chunkの情報です。それぞれのconfigサーバは、すべてのchunkの情報のコピーを完全に持ちます。configサーバ間での一貫性を確実にするために 2 phase commitが使われています。configサーバーは独自のレプリケーションモデルを持ち、replica setとしては稼働していないことに注意して下さい。

configサーバがダウンした場合、shardの追加や移動ができないので、クラスタのメタデータは読み込み専用になります。データの読み書きは通常通りできます。

ルーティングプロセス

mongos プロセスとは、クラスターの様々なコンポーネントがまるでが1つのシステムに見えるようにするためのルーティングやコーディネートをするプロセスと考えてください。クライアントからのリクエストを受けた時、 mongos プロセスがそのリクエストを適切なサーバーにルーティングし、各サーバーの返す結果をマージしてクライアント側に送信します。

mongos プロセスは永続的な状態にはありません、むしろconfingサーバーの起動時に状態をpullします。そしてconfigサーバー上のあらゆる変化は全ての mongos プロセスに伝搬されます。

mongos プロセスはどのサーバー上でも動かせます。shardサーバーと同一のサーバー上で動かすこともできますが、軽量なので各アプリケーションサーバー上に存在させることもできます。同時起動させる mongos プロセスの数には制限がありませんので、互いに協調動作はしません。

オペレーションタイプ

shardされたシステムでは、二つのスタイルのオペレーションを持ちます。 globaltargeted です。

targeted オペレーションでは、 mongos のshardへのアクセスは最小限です。多くの場合1つだけです。この操作はとても効率的です。

globalオペレーションは、 mongos プロセスはシステム内の(ほぼ)すべてのshardにアクセスします。

次のテーブルは、様々なオペレーションとタイプです。   下記の例では、 { x : 1 } をshardキーと仮定しています。この場合、shardキー"x"を含むオペレーションの多くはtargetedオペレーションに該当し、適切なshardからのみアクセスを行います。

Operation Type
Comments
db.foo.find( { x : 300 } )
Targeted
1つのshardでクエリー
db.foo.find( { x : 300, age : 40 } ) Targeted 1つのshardでクエリー
db.foo.find( { age : 40 } )
Global すべてのshardでクエリー
db.foo.find()
Global 順番
db.foo.find(...).count()
  find() オペレーションと同じ
db.foo.find(...).sort( { age : 1 } )
Global 並列
db.foo.find(...).sort( { x : 1 } )
Global 順番
db.foo.count()
Global 並列
db.foo.insert( <object> )
Targeted  
db.foo.update( { x : 100 }, <object> )
db.foo.remove( { x : 100 } )
Targeted  
db.foo.update( { age : 40 }, <object> )
db.foo.remove( { age : 40 } )
Global
 
db.getLastError()
   
db.foo.ensureIndex(...)
Global  

サーバーレイアウト

サーバーレイアウトは様々です。例えば、config、 mongosmongod をそれぞれのサーバで動かす方法です。しかし元々configサーバーへの負荷は少ないですのでやりすぎとも言えます。下図はリソース過剰にさせないように物理サーバをいくつかのプロセスで共有する方法を示しています。

その他の設定も可能です。例えば、サーバー:1-6 の全てで mongos を走らせます。または、アプリケーションサーバー:7 でも mongos を走らせます。 mongos をアプリケーションサーバで走らせる事のメリットは、localhost上でアプリケーションサーバーとmongosが通信できる事です。

Configuration

shardingは実際に一度組んでみることが理解の助けになります。shardクラスターは1台のマシンで構成可能です。設定を参照して下さい。


Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

IF YOU HAVE A QUESTION, POST IT TO THE USER GROUP.

These pages are fine for comments, but for questions, your best bet will always be the MongoDB User Group.

blog comments powered by Disqus