MongoDB で遅いクエリからアプリを保護する方法はありますか? 私のアプリケーションにはフィルターの可能性がたくさんあり、これらすべてのクエリを監視していますが、同時に、インデックス定義がないためにパフォーマンスが低下したくありません。
5 に答える
@ghik が述べたように、「notablescan」オプションを使用すると、インデックスを使用しないために遅いクエリを実行できなくなります。ただし、このオプションはサーバーに対してグローバルであり、運用環境での使用には適していません。また、テーブル スキャン以外のスロー クエリの原因から保護することもできません。
残念ながら、今すぐやりたいことを直接行う方法はないと思います。$maxTime または $maxScan クエリ パラメーターの追加を提案する JIRA チケットがあります。これは役に立ちそうなので、投票してください: https://jira.mongodb.org/browse/SERVER-2212。
現在、バージョン2.6
ではこれが可能です。彼らのプレスリリースでは、次のことがわかります。
MaxTimeMS を使用すると、オペレーターと開発者はクエリの自動キャンセルを指定できるため、リソース使用率をより適切に制御できます。
したがって、MaxTimeMSを使用すると、クエリの実行を許可する時間を指定できます。たとえば、特定のクエリを 200 ミリ秒以上実行したくありません。
db.collection.find({
// my query
}).maxTimeMS(200)
これの優れている点は、操作ごとに異なるタイムアウトを指定できることです。
コメントでOPの質問に答えるには。これにはグローバル設定はありません。理由の 1 つは、クエリによって最大許容時間が異なる可能性があることです。たとえば、ID で userInfo を検索するクエリを作成できます。これは非常に一般的な操作であり、超高速で実行する必要があります (そうでない場合は、何か間違ったことをしています)。そのため、200 ミリ秒を超えて実行することは許容できません。
しかし、1 日に 1 回実行する集計クエリもあります。この操作では、4 秒間実行しても問題ありません。ただし、10 秒以上は許容できません。したがって、maxTimeMS として 10000 を入れることができます。
クライアント側で利用可能なオプションがあります(maxTimeMS 2.6 リリース以降)。
サーバー側では、すべてのデータベースとすべての操作に影響を与えるため、魅力的なグローバルオプションはありません。システムが内部操作のために長時間実行する必要がある場合でも影響します (たとえば、レプリケーションの oplog を追跡します)。さらに、一部のクエリは設計上長時間実行しても問題ない場合があります。
これを解決する正しい方法は、スクリプトを介して現在実行中のクエリを監視し、長時間実行され、ユーザー/クライアントが開始したクエリを強制終了することです。その後、設計上長時間実行されているクエリの例外を作成したり、しきい値が異なるクエリを作成したりできます。さまざまなクエリ/コレクションなど。
その後、(シェルで) db.currentOp() メソッドを使用して、現在実行中のすべての操作を確認できます。フィールド「secs_running」は、操作が実行されている時間を示します。アプリケーション/クライアントによって開始されていない長時間実行される操作を強制終了しないように注意してください。これは、シャード クラスターでのチャンクの移行など、必要なシステム操作である可能性があります (一例として)。
現在、時間引数を渡すことでクエリを強制終了することはサポートされていないと思います。ただし、開発側では、プロファイラー レベルを 2 に設定できます。発行されたすべてのクエリがログに記録されます。そこから、どのクエリにどれだけの時間がかかるかを確認できます。私はそれがあなたが望んでいたものではないことを知っていますが、すべてのクエリがファットであるという洞察を得るのに役立ちます。アプリのロジックでは、それらのクエリが発生する可能性のあるケースを適切に処理する方法をいくつか持つことができます。私は通常、このアプローチを採用していますが、これが役に立ちます。