Docs Menu
Docs Home
/
MongoDBマニュアル
/ /

挿入のみのワークロードの分散ローカル書込み

項目一覧

  • Scenario
  • 手順

MongoDB タグ対応シャーディング を使用すると、管理者はシャードキーの範囲を定義し、その範囲を 1 つ以上のシャードにタグ付けすることで、シャーディングされたクラスター内のデータの分散を制御できます。

このチュートリアルでは、ゾーンとマルチデータセンターのシャーディングされたクラスターの配置とアプリケーション側のロジックを使用して、分散ローカル書込みをサポートし、レプリカセットの選挙やデータセンターに障害が発生した場合の高い書込み可用性をサポートします。

空のコレクションまたは存在しないコレクションをシャーディングする前にゾーンとゾーン範囲を定義することで、シャード コレクション操作は定義されたゾーン範囲のチャンクと、シャードキー値の全範囲をカバーする追加のチャンクを作成し、初期化を実行しますゾーン範囲に基づく チャンク分散 。 このように初期チャンクを作成して分散することで、ゾーン シャーディングの設定を迅速に行うことができます。 初期分散後、バランサーは今後のチャンク分散を管理します。

例については、「 空または存在しないコレクションのゾーンとゾーン範囲の事前定義」を参照してください。

重要

このチュートリアルで説明される概念には、特定の配置アーキテクチャとアプリケーション レベルのロジックが必要です。

これらの概念には、 MongoDBのシャーディングされたクラスターレプリカセット、およびゾーン の一般的な動作に関する知識が必要です。

このチュートリアルでは、挿入専用または挿入集中型のワークロードを前提としています。 このチュートリアルで説明されている概念と戦略は、高速な読み取りまたは更新を必要とするユースケースには適していません。

書込みに比べて読み取りは頻度が低く、優先順位が低い、挿入集中型のアプリケーションを例にしましょう。 アプリケーションはドキュメントをシャーディングされたコレクションに書込みますが、SLA または SLO をサポートするにはデータベースからのほぼ一貫したアップタイムが必要です。

次は、アプリケーションがデータベースに書込むドキュメントの形式の部分的なビューを表します。

{
"_id" : ObjectId("56f08c447fe58b2e96f595fa"),
"message_id" : 329620,
"datacenter" : "alfa",
"userid" : 123,
...
}
{
"_id" : ObjectId("56f08c447fe58b2e96f595fb"),
"message_id" : 578494,
"datacenter" : "bravo",
"userid" : 456,
...
}
{
"_id" : ObjectId("56f08c447fe58b2e96f595fc"),
"message_id" : 689979,
"datacenter" : "bravo",
"userid" : 789,
...
}

コレクションでは、 { datacenter : 1, userid : 1 }複合インデックスがシャードキーとして使用されます。

各ドキュメントのdatacenterフィールドを使用すると、個別のデータセンター値ごとにタグ範囲を作成できます。 datacenterフィールドがない場合、ドキュメントを特定のデータセンターに関連付けることはできません。

useridフィールドは、 datacenterと比較して、シャードキーに対して高濃度で低頻度のコンポーネントを提供します。

シャードキーの選択に関する一般的な手順については、「シャードキーの選択」を参照してください。

配置は、 alfabravoの 2 つのデータセンターで構成されています。 シャードにはshard0000shard0001の 2 つがあります。 各シャードは、3 つのメンバーを含むレプリカセットです。 shard0000は、 alfaに 2 つのノードを持ち、 bravoに 1 つの優先順位 0 のノードを持ちます。 shard0001は、 bravoに 2 つのノードを持ち、 alfaに 1 つの優先順位 0 のノードを持ちます。

高可用性のためのシャーディングされたクラスターのアーキテクチャ図

このアプリケーションでは、データセンターごとに 1 つのタグが必要です。 各シャードには、レプリカセット ノードの過半数を含むデータセンターに基づいて、1 つのタグが割り当てられます。 タグ範囲は、データセンターごとに 1 つずつ、2 つあります。

alfa Datacenter

このデータセンター上の過半数のノードを含むシャードにalfaとしてタグを付けます。

次の要素を使用してタグ範囲を作成します:

  • { "datacenter" : "alfa", "userid" : MinKey }の下限、

  • { "datacenter" : "alfa", "userid" : MaxKey }の上限、および

  • タグ alfa

bravo Datacenter

このデータセンター上の過半数のノードを含むシャードにbravoとしてタグを付けます。

次の要素を使用してタグ範囲を作成します:

  • { "datacenter" : "bravo", "userid" : MinKey }の下限、

  • { "datacenter" : "bravo", "userid" : MaxKey }の上限、および

  • タグ bravo

注意

MinKeyMaxKeyの値は比較用の特別な値です

構成されたタグとタグ範囲に基づいて、 mongosdatacenter : alfaを持つドキュメントをalfaデータセンターに、 datacenter : bravoを持つドキュメントをbravoデータセンターにルーティングします。

挿入または更新されたドキュメントが設定されたタグ範囲と一致する場合、そのドキュメントは関連するタグを持つシャードにのみ書き込むことができます。

MongoDB は、設定されたタグ範囲に一致しないドキュメントをクラスター内の任意のシャードに書込むことができます。

注意

上記の動作では、クラスターが定常状態で、設定されたタグ範囲に違反するチャンクがない状態である必要があります。 詳しくは、 バランサーの次のセクションを参照してください。

バランサーは、タグ付けされたチャンクを適切なシャードに移行します。 移行するまで、シャードには構成されたタグ範囲とタグに違反するチャンクが含まれる可能性があります。 バランシングが完了すると、シャードには、割り当てられたタグとタグ範囲に違反しない範囲のチャンクのみが含まれるようになります。

タグまたはタグ範囲を追加または削除すると、チャンクの移行が発生する可能性があります。 データセットのサイズと、タグ範囲が影響するチャンクの数によっては、これらの移行がクラスターのパフォーマンスに影響を与える可能性があります。 特定のスケジュールされた 中に バランサー Windowsを実行することを検討してください。スケジュール ウィンドウの設定方法については、「 バランシング ウィンドウのスケジュール」を参照してください。

デフォルトでは、アプリケーションは最も近いデータセンターに書込みます。 ローカル データセンターがダウンした場合、またはそのデータセンターへの書き込みが一定期間内に確認されない場合、アプリケーションはデータベースへのドキュメントの書込みを試みる前に、 datacenterフィールドの値を変更して他の利用可能なデータセンターに切り替えます。

アプリケーションは書込みタイムアウトをサポートしています。 アプリケーションは、書込み保証を使用して、各書込み操作のタイムアウトを設定します。

アプリケーションで書込みまたはタイムアウトのエラーが発生した場合、各ドキュメントのdatacenterフィールドを変更し、書込みを実行します。 これにより、ドキュメントは他のデータセンターにルーティングされます。 両方のデータセンターがダウンしている場合は、書込みは成功しません。 「書込み失敗の解決 」を参照してください。

アプリケーションは、「ダウン」とマークされたデータセンターへの接続を定期的にチェックします。 接続が復元された場合、アプリケーションは通常の書込み操作を引き続き実行できます。

切り替えロジックと、データセンター間のクライアントトラフィックを処理するためのロードバランサーまたは同様のメカニズムを考慮すると、アプリケーションは、特定のドキュメントが 2 つのデータセンターのどのデータセンターに書き込まれたかを予測できません。 読み取り操作の一環としてドキュメントが見逃しないようにするには、クエリの一部としてdatacenterフィールドを含めブロードキャスト クエリを実行する必要があります。

アプリケーションは、レイテンシを削減するために の 読み込み設定( read preference nearest) を使用して読み取りを実行します。

タイムアウト エラーが報告されていても、書込み (write) 操作は成功する可能性があります。 アプリケーションは、エラーに応答してドキュメントを他のデータセンターに書き換えようとします。これにより、両方のデータセンターにドキュメントが重複する可能性があります。 アプリケーションは、読み取りロジックの一部として重複を解決します。

このアプリケーションには、1 つ以上の書込み (write) が失敗した場合、または設定された時間内に書込み (write) が確認されなかった場合に、データセンターを切り替えるロジックがあります。 アプリケーションは、ターゲット データセンターのタグに基づいてdatacenterフィールドを変更し、ドキュメントをそのデータセンターに送信します。

たとえば、アプリケーションがalfaデータセンターに書込みを試みる場合、次の一般的な手順に従います。

  1. datacenter : alfaを指定してドキュメントの書込みを試みます。

  2. 書き込みタイムアウトまたはエラーが発生すると、 alfaが一時的にダウンしているとしてログに記録されます。

  3. datacenter : bravoを変更して、同じドキュメントの作成を試みます。

  4. 書き込みタイムアウトまたはエラーが発生すると、 bravoが一時的にダウンしているとしてログに記録されます。

  5. alfabravoの両方がダウンしている場合は、 がログに記録とエラーを報告します。

書込み失敗の解決 」を参照してください。

続行するには、ターゲットの mongosシャーディングされたクラスター に関連付けられている に接続する必要があります。シャードレプリカセットに直接接続してタグを作成することはできません。

1

alfaデータセンター内の各シャードにalfaタグを付けます。

sh.addShardTag("shard0000", "alfa")

bravoデータセンター内の各シャードにbravoタグを付けます。

sh.addShardTag("shard0001", "bravo")

任意のシャードに割り当てられたタグを確認するには、 sh.status()を実行します。

2

alfaデータベースの範囲を定義し、 sh.addTagRange()メソッドを使用してalfaタグに関連付けます。 このメソッドには次のものが必要です。

  • ターゲット コレクションの完全な名前空間。

  • 範囲の下限を含みます。

  • 範囲の排他的上限。

  • タグの名前。

sh.addTagRange(
"<database>.<collection>",
{ "datacenter" : "alfa", "userid" : MinKey },
{ "datacenter" : "alfa", "userid" : MaxKey },
"alfa"
)

bravoデータベースの範囲を定義し、 sh.addTagRange()メソッドを使用してbravoタグに関連付けます。 このメソッドには次のものが必要です。

  • ターゲット コレクションの完全な名前空間。

  • 範囲の下限を含みます。

  • 範囲の排他的上限。

  • タグの名前。

sh.addTagRange(
"<database>.<collection>",
{ "datacenter" : "bravo", "userid" : MinKey },
{ "datacenter" : "bravo", "userid" : MaxKey },
"bravo"
)

MinKeyMaxKeyの値は比較用の特別な値として予約されています。 MinKeyは常に他のすべての可能な値よりも小さいとみなされ、 MaxKeyは常に他のすべての可能な値よりも大きいとみなされます。 構成された範囲では、各datacenterのすべてのユーザーがキャプチャされます。

3

次回バランサーが実行されると、構成されたゾーンに従ってシャード全体にデータが移行されます。

バランシングが完了すると、 alfaとタグ付けされたシャードにはdatacenter : alfaのドキュメントのみが含まれ、 bravoとタグ付けされたシャードにはdatacenter : bravoのドキュメントのみが含まれる必要があります。

sh.status()を実行して、チャンクの分散を確認できます。

アプリケーションのデフォルトのデータセンターがダウンしているかアクセスできない場合、アプリケーションはdatacenterフィールドを他のデータセンターに変更します。

たとえば、アプリケーションは、デフォルトで次のドキュメントをalfaデータセンターに書込み込もうとします。

{
"_id" : ObjectId("56f08c447fe58b2e96f595fa"),
"message_id" : 329620,
"datacenter" : "alfa",
"userid" : 123,
...
}

アプリケーションが書込み試行時にエラーを受け取った場合、または書込み確認に時間がかかりすぎる場合、アプリケーションはデータセンターが使用できないとしてログに記録され、 datacenterフィールドが変更され、 bravoデータセンターを指すようにします。

{
"_id" : ObjectId("56f08c457fe58b2e96f595fb"),
"message_id" : 329620,
"datacenter" : "bravo",
"userid" : 123,
...
}

アプリケーションは、 alfaデータセンターの接続を定期的にチェックします。 データセンターに再びアクセスできるようになると、アプリケーションは通常の書込みを再開できます。

注意

特にエラーがタイムアウトに関連していた場合、 datacenter : alfaへの最初の書込み (write) は成功した可能性があります。 その場合、 message_id : 329620を含むドキュメントは両方のデータセンターに複製される可能性があります。 アプリケーションは、読み取り操作の一部として重複を解決する必要があります。

アプリケーションの切り替えロジックにより、ドキュメントの重複が可能になります。 読み取りを実行する際、アプリケーションはアプリケーション層上の重複するドキュメントを解決します。

次のクエリは、 userid123であるドキュメントを検索します。 useridはシャードキーの一部ですが、クエリにはdatacenterフィールドが含まれていないため、対象を絞った読み取り操作は実行されないことに注意してください。

db.collection.find( { "userid" : 123 } )

結果には、 329620message_idを持つドキュメントが MongoDB に 2 回挿入されたことが示されています。これは遅延書込み (write) 確認応答が原因と考えられます。

{
"_id" : ObjectId("56f08c447fe58b2e96f595fa"),
"message_id" : 329620
"datacenter" : "alfa",
"userid" : 123,
data : {...}
}
{
"_id" : ObjectId("56f08c457fe58b2e96f595fb"),
"message_id" : 329620
"datacenter" : "bravo",
"userid" : 123,
...
}

アプリケーションは、重複を無視して 2 つのドキュメントの 1 つを取得するか、ドキュメントが 1 つだけになるまで重複を削除しようとします。

重複を削除する方法の 1 つは、 ObjectId.getTimestamp()メソッドを使用して_idフィールドからタイムスタンプを抽出することです。 その後、アプリケーションは最初に挿入されたドキュメントまたは最後に挿入されたドキュメントを保持できます。 これでは、 _idフィールドが MongoDB ObjectId()を使用していることが前提となります。

たとえば、 ObjectId("56f08c447fe58b2e96f595fa")が含まれるドキュメントでgetTimestamp()を使用すると、次の値が返されます。

ISODate("2016-03-22T00:05:24Z")

ObjectId("56f08c457fe58b2e96f595fb")とともにドキュメントでgetTimestamp()を使用すると、次の結果が返されます。

ISODate("2016-03-22T00:05:25Z")

戻る

アプリケーションまたはカスタマー別のセグメント化

項目一覧