重要なアプリケーションを構築する場合は、本番環境で発生する可能性のある予期しないイベントに備えることが重要です。 これには、予期しない低速クエリ、インデックスの欠落、またはワークロード量の急増が含まれます。
MongoDB Atlasは、先を見越して準備し、状況に対応できるようにする既存の機能を提供することで、回復力のあるアプリケーションを構築するのに役立ちます。 回復力のあるアプリケーションを構築するには、次のクラスター回復力とアプリケーション、およびクライアント側のベストプラクティスを使用してMongoDBデプロイを構成することをお勧めします。
クラスターの回復力
クラスターの回復力を向上させるには、クラスターをMongoDB 8.0にアップグレードします。 MongoDB 8.0では、回復力に関連する次のパフォーマンスの向上と新機能が導入されています。
メモリ管理の改善
アプリケーションを本番環境で安全に実行するには、ヘッドルームが許容されるメモリ使用率を確認するのが重要です。ノードの使用可能なメモリが不足した場合、 mongodプロセスを終了するLinuxメモリ不足強制終了の影響を受けやすくなる可能性があります。
MongoDB8.0 はアップグレードされた TCMalloc をすべての配置に自動的に使用するため、平均的なメモリ フラグメントの増加が時間の経過とともに減少します。フラグメント度が低いことで、ピーク負荷時の動作安定性が向上し、メモリ使用率が全体的に向上します。
操作拒否フィルター
意図しないリソース集中操作は、迅速に処理されない場合、本番環境で問題が発生する可能性があります。
MongoDB 8.0では、操作拒否フィルターを使用して、これらの操作の影響を最小限に抑えることができます。 操作拒否フィルターを使用すると、そのクエリシェイプでクエリを再度有効にするまで、実行中中のクエリを拒否するようにMongoDBを構成できます。
つまり、低速クエリを特定したら、アプリケーションチームが低速クエリの影響を軽減するためにクエリを修正するのを待つ必要はありません。 代わりに、クエリプロファイラー、リアルタイム パフォーマンス パネル、またはクエリ ログのいずれかでクエリのパフォーマンスが低下していることに気付いたら、そのクエリシェイプに 拒否フィルター を設定できます。 その後、 MongoDBはその受信クエリシェイプの新しいインスタンスが実行されないようにします。 クエリを修正したら、クエリシェイプを再度有効にできます。
次の場合は、操作拒否フィルターを使用する必要があります。
修正の進行中に低速クエリの影響を迅速に排除します。
過負荷時は、重要でないクエリを拒否して、より重要なワークロードを優先します。
最大リソース使用率に近い場合は、クラスターに時間を与えて回復します。
Atlas UIでの低速クエリの識別と拒否
Atlas UIで操作拒否フィルターを使用するには、次の手順に従います。
Atlas で、プロジェクトの Clusters ページに移動します。
まだ表示されていない場合は、希望するプロジェクトを含む組織を選択しますナビゲーション バーのOrganizationsメニュー
まだ表示されていない場合は、ナビゲーション バーのProjectsメニューから目的のプロジェクトを選択します。
サイドバーで、 Database見出しの下のClustersをクリックします。
[ Clusters(クラスター) ] ページが表示されます。
Go to the Query Profiler for the specified cluster within the current project.
クラスターの名前をクリックすると、Cluster サイドバーが開きます。
Cluster サイドバーで Query Insights をクリックします。
[Query Profiler] タブをクリックします。
特定のクエリシェイプの操作を拒否します。
setQuerySettingsdb.adminCommand()メソッドでqueryShapeHash を使用して、拒否するクエリシェイプを指定する を渡します。
注意
例については、「 操作拒否フィルターによる低速クエリのブロック 」を参照してください。
拒否またはタイムアウト後にクエリを監視する
クラスター サイドバーの メトリクス で、クエリがその後実行される方法をモニターできます。
Atlas で、プロジェクトの Clusters ページに移動します。
まだ表示されていない場合は、希望するプロジェクトを含む組織を選択しますナビゲーション バーのOrganizationsメニュー
まだ表示されていない場合は、ナビゲーション バーのProjectsメニューから目的のプロジェクトを選択します。
サイドバーで、 Database見出しの下のClustersをクリックします。
[ Clusters(クラスター) ] ページが表示されます。
読み取り操作のクラスターレベルのタイムアウト
本番環境に到達する前に、開発プロセスでクエリの効率を慎重に検討することが重要です。 例外は常に発生する可能性がありますが、非効率的なクエリに対して先を見越して軽減することで、クラスターのパフォーマンスの問題を防ぐことができます。
MongoDB8.0 では、サーバー側の がクラスターに取り込まれるインデックスなし操作からクエリを保護できます。操作がこのタイムアウトを超えると、 MongoDBdefaultMaxTimeMS は操作をキャンセルして、クエリが長時間実行中すぎてリソースが保持されるのを防ぎます。これにより、次のことが可能になります。
タイムアウトを設定する責任を、個々のアプリケーションチームからデータベースフォーカス チームに移行します。
クエリにインデックスがない場合のコレクションスキャンの影響を最小限に抑えます。
コストのかかる操作に対して最後のラウンドの軽減を用意することで、本番環境に移行します。
分析クエリなど、異なるタイムアウトを必要とするクエリがある場合は、 maxTimeMS メソッドで操作レベルのタイムアウトを設定することで、それらを上書きできます。
Atlas Administration APIで読み取り操作のデフォルト タイムアウトを設定する
defaultMaxTimeMSAtlas Administration APIを通じて パラメーターを設定するには、「 1 つのクラスターの高度な構成オプションを更新する 」を参照してください。
Atlas UIでの読み取り操作のデフォルト タイムアウトの設定
defaultMaxTimeMSAtlas UIで パラメータを設定するには、次の手順に従います。
Atlas で、プロジェクトの Clusters ページに移動します。
まだ表示されていない場合は、希望するプロジェクトを含む組織を選択しますナビゲーション バーのOrganizationsメニュー
まだ表示されていない場合は、ナビゲーション バーのProjectsメニューから目的のプロジェクトを選択します。
サイドバーで、 Database見出しの下のClustersをクリックします。
[ Clusters(クラスター) ] ページが表示されます。
設定オプションに移動します。
既存のクラスターがある場合は、[ クラスターの編集 ]ページに移動します。
新しいクラスターを作成している場合は、 Select a versionドロップダウンから [ MongoDB 8.0 ] を選択します。
[Additional Settings] をクリックします。
下にスクロールしてMore Configuration Options ] をクリックします。
強制終了された操作の動作を確認するには、「 拒否またはタイムアウト後にクエリを監視する 」を参照してください。詳しくは、「defaultMaxTimeMS と読み取り操作のデフォルト タイムアウトの設定 」を参照してください。
シャーディングされていないコレクションの影響を分離する
シャーディングにより、クラスターを水平方向に増やすできます。 MongoDBを使用すると、一部のコレクションをシャーディングしながら、同じクラスター内の他のコレクションはシャーディングされないままにできます。新しいデータベースを作成すると、クラスター内のデータ量が最も少ないシャードがデフォルトでそのデータベースのプライマリシャードとして選択されます。そのデータベースのシャーディングされていないコレクションは、デフォルトでそのプライマリシャードに配置されます。これにより、特にワークロードの増加が プライマリ シャード のワークロードディングされていないコレクションに集中する場合、プライマリシャードロードの増加に伴いプライマリシャードへのトラフィックが増加する可能性があります。
このワークロードをより分散するために、 MongoDB では、8.0 moveCollectionコマンドを使用して、シャーディングされていないコレクションをプライマリシャードから他のシャードに移動できます。これにより、アクティブで多目的なコレクションを、リソース使用量の少ないシャードに配置できます。これを使用すると、次のことが可能になります。
大規模で複雑なワークロードのパフォーマンスを最適化します。
リソース使用率の向上を実現します。
シャード間で日付をより均等に分散します。
次の状況では、コレクションを分離することをお勧めします。
高スループットのシャーディングされていないコレクションが複数あるためにプライマリシャードに重大なワークロードが発生した場合。
シャーディングされていないコレクションでは将来、増加が予想され、他のコレクションのボトルネックになる可能性があります。
クラスターごとに 1 コレクションの配置設計を実行中していて、優先順位やワークロードに基づいてそれらのカスタマーを分離したいと考えています。
シャードには、シャーディングされていないコレクションの数が含まれているため、データ量が按分されています。
を使用してシャーディングされていないコレクションを移動する方法については、「mongosh コレクションの移動 」を参照してください。
アプリケーションとクライアント側のベストプラクティス
MongoDB 配置とドライバー ライブラリの機能を構成して、ネットワーク停止やフェイルオーバー イベントに耐性のあるアプリケーションを作成できます。 MongoDB Atlas の 常時オン 機能を活用するアプリケーション コードを作成するには、次のタスクを実行する必要があります。
majorityアプリケーションに適した の書込み保証 (write concern)と読み取り保証 (read concern)を使用します。
最新のクライアント ライブラリのインストール
MongoDBクライアント ライブラリから、ご使用の言語の最新のクライアントライブラリをインストールします。クライアント ライブラリは、アプリケーションからのクエリをデータベースに接続して中継します。最新のクライアントライブラリを使用すると、最新のMongoDB機能が有効になります。
次に、アプリケーションに依存関係をインポートします。
接続文字列
注意
Atlas には、事前構成された接続文字列が用意されています。事前構成された string をコピーする手順については、「 Atlas が提供する接続文字列 」を参照してください。
Atlas クラスター内のすべてのノードを指定する接続文字列を使用して、アプリケーションをデータベースに接続します。クラスターでレプリカセットの選挙が実行され、新しいプライマリが選択された場合、クラスター内のすべてのノードを指定する接続文字列は、アプリケーションロジックなしで新しいプライマリを検出します。
Atlas Infinite クラスターでは、ストレージレイヤーはクラスターのノード間での選挙ではなくフェイルオーバーを調整し、すべてのノードを指定する接続文字列によって新しいプライマリが同じ方法で検出されます。詳細については、「 レプリケーションとフェイルオーバー 」を参照してください。
次のいずれかを使用して、クラスター内のすべてのノードを指定できます。
標準接続文字列形式 、または
DNS シードリスト接続形式(Atlas で推奨)。
接続文字列では、オプション(retryWrites と writeConcern など)を指定することもできます。
Atlas は、プライベート エンドポイント サービスのロード バランサーを使用して、シャーディングされたクラスター用に最適化された SRV接続文字列を生成できます。最適化された接続文字列を使用する場合、Atlasmongos はアプリケーションとシャーディングされたクラスター間の ごとの接続数を制限します。mongos あたりの接続数を制限すると、接続数が急増した際のパフォーマンスが向上します。
プライベートエンドポイントの背後にあるシャーディングされたクラスターに最適化された接続文字列の詳細については、プライベートエンドポイントを使用してシャーディングされたクラスターの接続パフォーマンスを最適化するにはどうすればよいですか。
Atlas が提供する接続文字列
Atlas クラスター インターフェースから接続文字列をコピーする場合、接続文字列 はクラスター用に事前構成され、DNS シードリスト形式を使用し、回復力のために推奨されるretryWrites とw (書込み保証(write concern))オプションが含まれます。
Atlas から接続文字列 URI をコピーするには、次の手順に従います。
Atlas で、プロジェクトの Clusters ページに移動します。
まだ表示されていない場合は、希望するプロジェクトを含む組織を選択しますナビゲーション バーのOrganizationsメニュー
まだ表示されていない場合は、ナビゲーション バーのProjectsメニューから目的のプロジェクトを選択します。
サイドバーで、 Database見出しの下のClustersをクリックします。
[ Clusters(クラスター) ] ページが表示されます。
接続文字列 URI をコピーします。
接続文字列またはドライバー全体のサンプルをアプリケーション コードにコピーします。 データベースユーザーの認証情報を提供する必要があります。
注意
このガイドでは、接続文字列による SCRAM認証を使用します。 X.509 証明書を使用して認証する方法については、「 X.509 」を参照してください。
接続文字列を使用して、アプリケーション内で MongoDB クライアントをインスタンス化します。
再試行可能な書込みと読み取り
注意
MongoDB はデフォルトで書込みと読み取りの両方を 1 回再試行します。
再試行可能な書き込み
再試行可能な書込み を使用して、特定の書込み操作が失敗した場合に 1 回再試行します。 Atlas から接続文字列をコピーした場合は、"retryWrites=true" が含まれます。独自の接続文字列を指定する場合は、クエリ"retryWrites=true" パラメータとして を含めます。
書き込みを 1 回だけ 再試行する ことは、アプリケーションが正常な プライマリ ノード を一時的に見つけられない場合に、一時的なネットワークエラーやレプリカセットの選挙を処理するための最善の戦略です。 再試行が成功すると、操作全体が成功し、エラーは返されません。 操作が失敗した場合は、次の理由が原因で失敗した可能性があります。
永続的なネットワークエラー
無効なコマンド
操作が失敗した場合、アプリケーションは自分自身を処理する必要があります。
再試行可能な読み取り
読み取り操作は、失敗すると 1 回自動的に再試行されます。読み取りを再試行するために追加の構成は必要ありません。
書込み保証 (write concern) と読み取り保証 (read concern)
書込み保証 (write concern) と読み取り保証 (read concern) を使用して、アプリケーションの整合性と可用性を調整できます。 懸念が深い場合は、データベース操作により強力なデータ整合性保証が必要になりますが、整合性要件を緩和すると可用性が向上します。
例
アプリケーションが金銭の残高を処理する場合、整合性は非常に重要です。 majorityの書込み保証と読み取り保証を使用して、古いデータやロールバックされる可能性のあるデータからの読み取りを行わないようにできます。
あるいは、アプリケーションが 1 秒ごとに数百のセンサーからの温度データを記録する場合、最新の読み取り値を含まないデータを読み取る場合は問題が発生しない場合があります。 整合性要件を緩和して、そのデータへのアクセスをより速くできます。
書込み保証 (write concern)
接続文字列URImajority を使用して、Atlasレプリカセットの書込み保証 (write concern)レベルを設定できます。データがデータベースに正常に書き込まれ、永続化されるようにするには、 書込み保証 (write concern)を使用します。これは推奨のデフォルトであり、ほとんどのユースケースで十分です。 Atlas から接続文字列をコピーした場合は、"w=majority" が含まれます。
majorityなど、確認応答が必要な書込み保証を使用する場合は、そのレベルの確認応答を実現するための書込みの最大時間制限を指定することもできます。
すべての書込み (write) の wtimeoutMS接続文字列パラメータ、または
単一の 書込み (write)操作の wtimeout オプション。
時間制限を使用するかどうかと使用する値は、アプリケーションのコンテキストによって異なります。
Atlas Infinite クラスターでは、ストレージレイヤーが書込み (write) を確認するため、設定できる書込み保証 (write concern) の値は異なります。詳細については、「 Atlas Infinite クラスターの書込み保証 (write concern) 」を参照してください。
重要
書込み (write) に時間制限を指定せず、書込み保証 (write concern) レベルが達成できない場合、書込み (write) 操作は無期限にハングします。
読み取り保証(read concern)
接続文字列URI を使用して、Atlasレプリカセットの読み取り保証 (read concern)レベルを設定できます。理想的な読み取り保証 (read concern)はアプリケーションの要件によって異なりますが、ほとんどのユースケースではデフォルトで十分です。デフォルトの読み取り保証を使用する場合、接続文字列パラメーターは必要ありません。
読み取り保証を指定すると、アプリケーションが Atlas から受信するデータの保証が強化されます。
注意
アプリケーションが使用する書込み保証 (write concern) と読み取り保証 (read concern)の特定の組み合わせは、操作順序の保証に影響します。これは 因果整合性 と呼ばれます。因果整合性の保証の詳細については、「 因果整合性、読み取り保証、書込み保証 」を参照してください。
Error Handling
再試行可能な書き込みで処理されていないコマンド、ネットワークの停止、ネットワークエラーはエラーを返します。エラーの詳細については、ドライバーのAPIドキュメントを参照してください。
たとえば、アプリケーションが、データベースの コレクションで既に使用されている_id値を含むドキュメントを挿入しようとすると、ドライバーは次のようなエラーを返します。
適切なエラー処理を行わないと、エラーによってアプリケーションが再起動されるまでリクエストの処理がブロックされる可能性があります。
アプリケーションは、クラッシュしたり副作用のないエラーを処理する必要があります。 コレクションに重複する_idを挿入するアプリケーションの以前の例では、そのアプリケーションは次のようにエラーを処理できます。
この例の挿入操作では、 _idフィールドが一意である必要があるため、2 回目に呼び出されるときに「重複キー」エラーがスローされます。 エラーがキャッチされ、クライアントに通知され、アプリは実行を続行します。 しかし、挿入操作は失敗します。ユーザーに メッセージを表示するか、操作を再試行するか、または別の操作を実行するかは、ユーザーが決定する必要があります。
エラーは常にログに記録する必要があります。 これ以上の処理エラーを発生させる一般的な戦略は次のとおりです。
エラーを、エラー メッセージとともにクライアントに返します。 これは、エラーを解決できず、アクションが完了できないことをユーザーに通知する必要がある場合に適した戦略です。
バックアップ データベースに書き込みます。 これは、エラーを解決できないが、リクエスト データが失われるリスクを避けたい場合に適した戦略です。
アプリケーションのコンテキストに最適な戦略を選択する必要があります。
例
重複キー エラーの例では、エラーをログに記録する必要がありますが、操作は成功しないため、再試行しないでください。 代わりに、フォールバック データベースに書き込みを行い、後でそのデータベースの内容を確認して、情報が失われることを確認することができます。 ユーザーは他に何もする必要がなく、データが記録されるため、クライアントにエラーメッセージを送信しないことを選択できます。
ネットワークエラーの計画
操作が無期限にハングし、アプリケーションが新しい操作を実行する際にブロックされる場合は、エラーを返すことが推奨されます。 maxTimeMS メソッドを使用して、個々の操作に時間制限を設定でき、その時間制限を超えた場合にアプリケーションが処理するエラーを返します。
各操作に設定する時間制限は、その操作のコンテキストによって異なります。
例
アプリケーションがinventoryコレクションから簡単な製品情報を読み取って表示する場合、これらの読み取り操作にかかる時間は 1 時間のみであることがかなり確実です。 クエリの実行時間が異常に長い場合は、ネットワークの問題が永続していることを示す適切なインジケーターです。 この操作でmaxTimeMSを 5000、つまり 5 秒に設定すると、アプリケーションはネットワークの問題があることを確認するとすぐにフィードバックを受け取ることを意味します。
フェイルオーバーのテスト
マテリアライズドテストの一環として、Atlas は定期的なメンテナンスや特定の構成変更のために、レプリカセットの選挙を自動的に実行します。
アプリケーションがレプリカセットの選挙に対して回復力があるかどうかを確認するには、フェイルオーバー イベントをシミュレートしてフェイルオーバー プロセスをテストします。
回復力のあるサンプルアプリケーション
サンプルアプリケーションには、ネットワーク停止やフェイルオーバー イベントに対する回復力を確保するために、次の推奨事項をまとめています。
Atlas が提供する接続文字列を、再試行可能な書き込み、過半数の書込み保証(write concern)、デフォルトの読み取り保証(read concern)とともに使用します。
maxTimeMS メソッドを使用して操作時間制限を指定します。
maxTimeMSを設定する方法については、特定の ドライバーのドキュメント を参照してください。重複キーとタイムアウトのエラーを処理します。
アプリケーションは、クライアントがユーザー レコードを作成または一覧表示できるHTTP APIです。これにより、GET および POST リクエスト ( http://localhost:3000 )を受け入れるエンドポイントが公開されます。
方式 | エンドポイント | 説明 |
|---|---|---|
|
|
|
|
| リクエスト本文に |