データの大幅な増加には、特に単一のサーバーで処理される場合のスループット操作の低下というコストが伴います。ただし、サーバーの数を増やし、これらのサーバーの複数の数にデータを分散することで、このパフォーマンスを向上させることができます。この記事「MongoDBのレプリカセット」では、データの高可用性を確保するだけでなく、スループット操作を改善する方法について詳しく説明しました。このプロセスは、MongoDBのシャーディングに言及せずに完全に達成することはできません。
MongoDBのシャーディングとは
MongoDBは、分散プラットフォーム全体でクラスター内で実行できるようにスケーラブルになるように柔軟に設計されています。このプラットフォームでは、データはストレージ用に複数のサーバーに分散されます。このプロセスは、シャーディングと呼ばれるものです。単一のサーバーがストレージのために大量のデータにさらされている場合、ストレージスペースが不足する可能性があります。さらに、読み取りや書き込みなどの非常に重要なスループット操作が大きな影響を受ける可能性があります。 MongoDBの水平スケーリング機能を使用すると、データを複数のマシンに分散して、最終的に負荷分散を改善できます。
MongoDBシャード
シャードは、シャードクラスターで使用されるデータサブセットをホストするレプリカセットと見なすことができます。いくつかのデータセットを持つ特定のmongodインスタンスの場合、データは分割され、この場合はシャードである複数のデータベースに分散されます。基本的に、いくつかの異なるシャードは独立したデータベースとして機能しますが、集合的にそれらは論理データベースを構成します。シャードは、このシャードがホストするデータの量が少ないことに加えて、シャードが処理する必要のある操作の数を減らすことにより、データベース全体で実行されるワークロードを減らします。このメトリックは、クラスターを水平方向に拡張する余地を与えます。シャーディングの単純なアーキテクチャを以下に示します。
クライアントアプリケーションから送信されたデータは、サーバードライバーによってインターセプトされ、ルーターに送られます。次に、ルーターはサーバー構成を調べて、シャードサーバーで読み取りまたは書き込み操作を適用する場所を決定します。一言で言えば、書き込みなどの操作の場合、どのシャードがホストになるレコードであるかを指示するインデックスがあります。データベースに4つのシャードに分散された1TBのデータ容量があり、各シャードが256GBのこのデータを保持するとします。シャードが処理できるデータの量が減ると、操作を非常に高速に実行できます。次の場合は、データベースでシャードクラスターの使用を検討する必要があります。
- 将来的には、データ量がシングルインスタンスのストレージ容量を超えると予想されます。
- 単一のMongodBインスタンスで書き込み操作を実行できない場合
- アクティブなワーキングセットのサイズが大きくなる代わりに、ランダムアクセスメモリRAMが不足します。
シャーディングには、追加のリソースに加えて、アーキテクチャの複雑さが増します。ただし、データが容量を超えている場合は非常に面倒なので、データが大きくなる前の早い段階でシャーディングを実行することをお勧めします。
MongoDBシャードキー
ご存知のとおり、MongoDBのドキュメントには、値を保持するためのフィールドがあります。シャーディングを展開するときは、データの分割に使用するコレクションからフィールドを選択する必要があります。選択したこのフィールドは、コレクション内のドキュメントを複数のシャードに分割する方法を決定するシャードキーです。簡単な例では、データに学生、クラスの教師、マークというフィールド名が含まれている場合があります。インデックスの学生、別の1人の教師、およびマークを含むドキュメントを含む1つのシャードセットを決定できます。ただし、データをランダムに分散する必要がある場合があるため、ハッシュ化されたシャードキーを使用してください。ハッシュされたシャードキーの他に、データの分割に使用されるシャードキーの範囲がありますが、2つの主要なカテゴリは、インデックス付きフィールドとインデックス付き複合フィールドです。
シャードキーの選択
シャーディング戦略の機能、機能、およびパフォーマンスを向上させるには、適切なシャーディングキーを選択する必要があります。選択基準は2つの要因に依存します:
- データのスキーマ構造。たとえば、値が増加または減少する(単調に変化する)可能性があるフィールドを考えることができます。これは、クラスター内の単一のシャードへのインサートの分散に影響を与える可能性があります。
- 書き込み操作を実行するためのクエリ構成の機能。
ハッシュシャードキーとは
これは、単一フィールドのハッシュ化されたインデックスをシャードキーとして使用します。ハッシュ化されたインデックスは、インデックス化されたフィールドの値のハッシュを含むエントリを維持するインデックスです。つまり、
{
"_id" :"5b85117af532da651cc912cd"
}
ハッシュ化されたインデックスを作成するには、mongoシェルでこのコマンドを使用できます。
db.collection.createIndex( { _id: hashedValue } )
hashedValue変数は、指定されたハッシュ値の文字列を表します。ハッシュシャーディングは、シャーディングされたクラスター全体でのデータ分散を促進し、それによってターゲット操作を削減します。ただし、シャードキーがほぼ同じドキュメントが同じシャード上にある可能性は低いため、mongoインスタンスは、特定のクエリ基準を満たすためにブロードキャスト操作を実行する必要があります。
範囲ベースのシャードキー
このカテゴリでは、データセットは選択されたフィールドキーの値の範囲に基づいてパーティション化されるため、パーティションの範囲が広くなります。つまり値が負の無限大から正の無限大まで続くテンキーがある場合、各シャードキーはその行内の特定のポイントに配置されます。この行はチャンクに分割され、各チャンクには特定の範囲の値があります。正確には、シャードキーがほぼ同じであるドキュメントは同じチャンクでホストされます。この手法の利点は、ルーターが特定のチャンクを持つシャードを選択するため、さまざまなクエリをサポートすることです。
最適なシャードキーの特徴
- 理想的なシャードキーは、単一のmongodインスタンスからクエリ操作を返すようにmongosプログラムを拡張するために、単一のシャードをターゲットにできる必要があります。プライマリフィールドであるキーはこれを特徴づけます。つまり埋め込まれたドキュメントではありません。
- 高度なランダム性を持っている。つまり、このフィールドはほとんどのドキュメントで利用できるはずです。これにより、書き込み操作がシャード内に確実に分散されます。
- 簡単に分割できるようにします。簡単に分割できるシャードキーを使用すると、データの分散が増え、シャードが増えます。
本番クラスター展開のコンポーネント
上記のアーキテクチャに関して、本番シャードクラスタには次のものが必要です。
- Mongos/クエリルーター。これらは、アプリケーションドライバーとデータベース自体の間のサーバーとして機能するmongoインスタンスです。デプロイでは、ロードバランサーは、単一のクライアントからの接続が同じモンゴに到達できるように構成されます。
- シャード。これらは、同じシャードキー定義を共有するドキュメントがホストされるパーティションです。データの可用性を高めるには、少なくとも2つ必要です。
- 構成サーバー:異なるマシンに3つの個別の構成サーバーを配置することも、複数のシャードクラスターを使用する場合はそれらのグループをグループ化することもできます。
シャードクラスターの展開
次の手順により、シャードクラスターの展開に向けた明確な方向性がわかります。
-
構成サーバーのホストを作成しています。デフォルトでは、サーバーファイルは/ data / configdbディレクトリにありますが、これはいつでも好みのディレクトリに設定できます。データディレクトリを作成するためのコマンドは次のとおりです。
$ mkdir /data/configdb
-
コマンドを使用してそれぞれのポートとファイルパスを定義することにより、構成サーバーを起動します
$ mongod --configsvr --dbpath /data/config --port 27018
このコマンドは、ポート27018でconfigという名前のデータディレクトリ内の構成ファイルを開始します。デフォルトでは、すべてのMongoDBサーバーはポート27017で実行されます。
-
構文を使用してmongosインスタンスを開始します:
$ mongo --host hostAddress --port 27018.
hostAddress変数には、ホストのホスト名またはIPアドレスの値が含まれます。
-
シャードサーバーでmongodを起動し、次のコマンドを使用して起動します:
mongod --shardsvr --replSet rs.initiate()
-
次のコマンドを使用して、ルーターでmongosを起動します。
mongos --configdb rs/mongoconfig:27018
-
クラスタにシャードを追加します。クラスタとしてデフォルトのポートが27017であるとすると、次のようにポート27018にシャードを追加できます。
mongo --host mongomaster --port 27017 sh.addShard( "rs/mongoshard:27018") { "shardAdded" : "rs", "ok" : 1 }
-
次のコマンドでシャード名を使用して、データベースのシャーディングを有効にします。
sh.enableSharding(shardname) { "ok" : 1 }
次のコマンドでシャードのステータスを確認できます:
sh.status()
この情報が表示されます
sharding version: { "_id" : 1, "minCompatibleVersion" : 5, "currentVersion" : 6, "clusterId" : ObjectId("59f425f12fdbabb0daflfa82") } shards: { "_id" : "rs", "host" : "rs/mongoshard:27018", "state" : 1 } active mongoses: "3.4.10" : 1 autosplit: Currently enabled: yes balancer: Currently enabled: yes Currently running: no NaN Failed balancer rounds in last 5 attempts: 0 Migration Results for the last 24 hours: No recent migrations databases: { "_id" : shardname, "primary" : "rs", "partitioned" : true }
シャードバランシング
シャードをクラスターに追加した後、一部のシャードが他のシャードよりも多くのデータをホストしている可能性があり、新しいシャードにはデータがないことに気付く場合があります。したがって、負荷のバランスを確保するために、いくつかのバックグラウンドチェックを実行する必要があります。バランシングは、データがクラスター内で再配布される基礎です。バランサーは不均一な分布を検出するため、バランスクォーラムに達するまでチャンクをあるシャードから別のシャードに移行します。
バランシングプロセスは、ワークロードのオーバーヘッドに加えて多くの帯域幅を消費し、これはデータベースの操作に影響を与えます。より良いバランス調整プロセスには以下が含まれます:
- 一度に1つのチャンクを移動します。
- 移行のしきい値に達したとき、つまり、特定のコレクションのチャンクの最小数とシャーディングされたコレクションのチャンクの最大数の差が生じたときに、バランシングを実行します。