FAQ
項目一覧
- MongoDB への接続中にエラーが発生するのはなぜですか?
- ノード ドライバーでの接続プーリングの仕組み
- "connectTimeoutMS"、"socketTimeoutMS"、"maxTimeMS" の違いは何ですか。
- クライアントが切断した場合、操作の実行はどうなりますか。
- ドライバーが使用できないソケットを閉じたことを確認するには
- ソケットがアクティブになる前にタイムアウトしないようにするにはどうすればよいですか。
- "connectTimeoutMS" と "socketTimeoutMS" の場合、"0" の値は何を意味しますか。
- 長時間実行される操作によるサーバーの速度低下を防ぐ方法
- keepAlive オプションの果たす役割
- 予期しないネットワーク動作が発生している場合は
- 低速操作による他の操作の遅延を防ぐには
- 接続stringがレプリカセットで有効であることを確認するには
このページには、よくある質問とその回答が含まれています。
Tip
このページで問題の解決策が見つからない場合は、次のステップやその他のリソースについての問題とヘルプページを参照してください。
MongoDB への接続中にエラーが発生するのはなぜですか?
MongoDB 配置への接続に問題がある場合は、考えられる解決策について接続トラブルシューティング ガイドを参照してください。
ノード ドライバーでの接続プーリングの仕組み
すべての MongoClient
インスタンスには、MongoDB トポロジー内の各サーバーに対する接続プールが組み込まれています。 接続プールはオンデマンドでソケットを開き、アプリケーション内の MongoDB への同時要求をサポートします。
各接続プールの最大サイズはmaxPoolSize
オプションによって設定され、デフォルトは100
になります。 サーバーへの使用中の接続数がmaxPoolSize
の値に達した場合、そのサーバーへの次のリクエストは、接続が利用可能になるまで待機します。
アプリケーションのリクエストをサポートするために必要なソケットに加えて、各MongoClient
インスタンスは、サーバーの状態を監視するために MongoDB トポロジー内のサーバーごとにさらに 2 つのソケットを開きます。 たとえば、3 ノードのレプリカセットに接続されたクライアントは、6 つの監視ソケットを開きます。 アプリケーションがmaxPoolSize
のデフォルト設定を使用し、プライマリ(デフォルト)ノードのみをクエリする場合、接続プールには最大106
の接続が存在できます。 アプリケーションが読み込み設定( read preference )を使用してセカンダリ ノードをクエリする場合、それらの接続プールは増大し、合計接続数は306
になる可能性があります。
1 つのプロセス内で多数の同時 MongoDB リクエストをサポートするには、 maxPoolSize
を増やすことができます。
接続プールにはレート制限があります。 maxConnecting
オプションによって、プールが並行して作成できる接続数が決定されます。 たとえば、 maxConnecting
の値が2
の場合、接続を同時にチェックアウトしようとする 3 番目のリクエストは、次のいずれかの場合にのみ成功します。
接続プールは接続の作成を完了し、プール内の接続数は
maxPoolSize
未満です。既存の接続がプールにチェックバックされます。
接続作成のレート制限により、既存の接続を再利用するドライバーの能力が向上します。
minPoolSize
オプションを使用して、各サーバーへの同時接続の最小数を設定できます。デフォルトは0
になります。 ドライバーは、このソケット数で接続プールを初期化します。 ソケットが閉じられ、ソケットの合計数(使用中とアイドル状態の両方)が最小値を下回る場合、最小値に達するまでさらにソケットが開かれます。
maxIdleTimeMS
オプションを設定することで、プール内で接続がアイドル状態を維持できる最大ミリ秒数を設定できます。 maxIdleTimeMS
の接続がアイドル状態になると、接続プールはそれを削除し、置き換えます。 このオプションのデフォルトは0
(制限なし)です。
MongoClient
の次のデフォルト構成はほとんどのアプリケーションで動作します。
const client = new MongoClient("<connection string>");
MongoClient
は、複数の同時リクエストをサポートします。 プロセスごとにクライアントを作成し、プロセス内のすべての操作で再利用します。 この方法は、リクエストごとにクライアントを作成するよりも効率的です。
ドライバーはソケットが利用可能になるまで待機できるリクエストの数を制限しません。負荷が急増したときにプールのサイズを境界のあるキューに制限するのはアプリケーションの責任です。 リクエストは、 waitQueueTimeoutMS
オプションで指定された時間だけ待機します。デフォルトでは0
(制限なし)です。
ソケットを対象にwaitQueueTimeoutMS
で定義された時間以上待機するリクエストでは、接続エラーが発生します。 すべての操作を完了することよりも、負荷急増中に操作の継続時間を制限することが重要な場合は、このオプションを使用します。
任意のリクエストによってMongoClient.close()
が呼び出されると、ドライバーはすべてのアイドル ソケットを閉じ、プールに返されるときに使用中のすべてのソケットを閉じます。 MongoClient.close()
を呼び出すと、非アクティブなソケットのみが閉じられ、実行中の操作は直接終了されません。 ドライバーは、関連付けられている操作が完了した場合にのみ、使用中のソケットを閉じます。 ただし、 MongoClient.close()
メソッドは既存のセッションとトランザクションを閉じるため、実行中の操作や開いているカーソルの動作に間接的に影響を与える可能性があります。
"connectTimeoutMS"、"socketTimeoutMS"、"maxTimeMS" の違いは何ですか。
設定 | 説明 |
---|---|
connectTimeoutMS |
TipMongoClient.connect がMongoDB Serverへの接続を確立するための許可時間を変更するには、代わりに デフォルト: 30000 |
socketTimeoutMS | socketTimeoutMS は、ドライバーが非アクティブなソケットを閉じる前に待機する時間を指定します。 デフォルト値では、ソケットをタイムアウトしない設定になっています。 このオプションはすでに接続されているソケットにのみ適用されます。 |
maxTimeMS | maxTimeMS は、サーバーが操作に到達した後、完了するまでサーバーが待機する最大時間を指定します。操作が指定された時間制限を超えて実行されると、タイムアウトのエラーが返されます。 maxTimeMS は個々の操作またはカーソルにのみ渡すことができます。 |
MongoClient
のオプション設定を指定するには、次のようにコンストラクターのoptions
オブジェクトで 1 つ以上の利用可能な設定を宣言します。
const client = new MongoClient(uri, { connectTimeoutMS: <integer value>, socketTimeoutMS: <integer value> });
利用可能なすべての設定を確認するには、「 MongoClientOptions 」を参照してください。 API ドキュメント。
maxTimeMS
を指定するには、タイムアウト指定を指定してmaxTimeMS()
メソッドを、 Cursor
を返す操作に連鎖させます。
const cursor = myColl.find({}).maxTimeMS(50);
クライアントが切断した場合、操作の実行はどうなりますか。
MongoDB Server バージョン4.2以降、クライアントの接続が切断されると、サーバーは集計や検索操作などの実行中の操作を終了します。 この動作に影響を受ける操作の完全なリストを確認するには、サーバー マニュアルのサーバー バージョン4.2リリースノートを参照してください。
クライアントの接続が切断されても、書込み操作などの他の操作は MongoDB Server 上で引き続き実行されます。 この動作により、クライアントが切断した後にアプリケーションが操作を再試行すると、データの不整合が発生する可能性があります。
ドライバーが使用できないソケットを閉じたことを確認するには
予期しないネットワーク動作が発生した場合、または MongoDB プロセスがエラーで失敗した場合、ドライバーが対応するソケットを正しく閉じたことを確認しないことがあります。
このような場合、ドライバーがソケットを正しく閉じることを確認するには、 socketTimeoutMS
オプションを設定します。 MongoDB プロセスがタイムアウトすると、ドライバーはソケットを閉じます。 アプリケーションが実行する最も遅い操作の予想される期間よりも 2 倍から 3 倍の長さの値をsocketTimeoutMS
に選択することをお勧めします。
ソケットがアクティブになる前にタイムアウトしないようにするにはどうすればよいですか。
接続プールが大きい場合でも、再接続リクエストは必ずしも削減されるわけではありません。 次の例で考えてみましょう。
アプリケーションの接続プール サイズが 5 ソケットで、 socketTimeoutMS
オプションが 5,000 ミリ秒に設定されている。 操作は平均して 3000 ミリ秒ごとに発生し、再接続リクエストは頻繁に発生します。 各ソケットは 5000 ミリ秒後にタイムアウトします。つまり、閉じないようにするには、すべてのソケットが 5000 ミリ秒中に何らかの操作を行う必要があります。
3000 ミリ秒ごとの 1 回のメッセージではソケットをアクティブに保つには十分ではないため、5000 ミリ秒後に一部のソケットはタイムアウトします。 過剰なソケット タイムアウトを回避するには、 maxPoolSize
オプションを指定してドライバーが接続プール内で維持できる接続の数を減らします。
MongoClient
に任意のmaxPoolSize
設定を指定するには、次のようにコンストラクターのoptions
オブジェクトでそれを宣言します。
const client = new MongoClient(uri, { maxPoolSize: <integer value>, });
"connectTimeoutMS" と "socketTimeoutMS" の場合、"0" の値は何を意味しますか。
connectTimeoutMS
またはsocketTimeoutMS
の値を0
に設定すると、アプリケーションはオペレーティング システムのデフォルトのソケット タイムアウト値を使用します。
長時間実行される操作によるサーバーの速度低下を防ぐ方法
タイムアウト値を指定することで、実行時間が長い操作によってサーバーが低速になるのを防ぐことができます。 maxTimeMS()
メソッドをCursor
を返す操作に連鎖させて、特定のアクションにタイムアウトを設定できます。
次の例えは、 maxTimeMS()
メソッドをCursor
を返す操作に連結する方法を示しています。
// Execute a find command await collection .find({ $where: "sleep(100) || true" }) .maxTimeMS(50);
keepAlive オプションの果たす役割
keepAlive
接続オプションは、 トランザクション制御プロトコル(TCP)のキープアライブ を有効にするかどうかを指定します TCP ソケット上。キープアライブを有効にすると、ドライバーは MongoDB 配置に定期的に ping を送信し、接続がアクティブかどうかを確認します。 この機能は、オペレーティング システムがSO_KEEPALIVE
ソケット オプションをサポートしている場合にのみ機能します。
keepAliveInitialDelay
オプションは、ドライバーがキープアライブを開始する前に待機するミリ秒数を指定します。
5.3 ドライバー バージョン リリースでは、これらのオプションは非推奨になりました。 ドライバーのバージョン 6.0 以降では、 keepAlive
オプションは永続的にtrue
に設定され、 keepAliveInitialDelay
は 300000 ミリ秒(300 秒)に設定されています。
警告
ファイアウォールがキープアライブ メッセージを無視または削除すると、削除された接続を識別できない可能性があります。
予期しないネットワーク動作が発生している場合は
アプリケーションと MongoDB 間のファイアウォールの構成が正しく行われていない場合、予期しないネットワーク動作が発生する可能性があります。 これらのファイアウォールは接続の削除が過剰になるため、予期しないエラーが発生する可能性があります。
ファイアウォールが次の動作を示していることを確認します。
ファイアウォールは接続を閉じるときに
FIN
パケットを送信し、ソケットが閉じられたことをドライバーに通知します。ファイアウォールはキープアライブ メッセージを許可します。
Tip
keepalive メッセージの詳細については、 keepAlive オプションとは何ですかを参照してください。 FAQ エントリー
低速操作による他の操作の遅延を防ぐには
同じMongoClient
インスタンスを使用して複数の MongoDB 操作を同時に実行すると、低速操作によって他の操作が遅れる可能性があります。 遅い操作では MongoDB への接続が専有され続け、そのため、追加の接続が利用可能になるまで他の操作が待機する恐れがあります。
MongoDB の低速操作が遅延の原因になっていると思われる場合は、次の方法を使用して、進行中のすべての操作のパフォーマンスを確認できます。
配置でデータベースプロファイラーを有効にします。 詳細については、サーバー マニュアルの「データベースプロファイラ」を参照してください。
db.currentOp()
MongoDB Shell コマンドを実行します。 詳細については、サーバー マニュアルのdb.currentOp()ドキュメントを参照してください。接続プールのモニタリングを有効にします。 詳細については、「接続プールのモニタリング 」を参照してください。
遅延の原因となっている操作を特定したら、これらの操作のパフォーマンスを向上させるようにしてください。 可能な解決策については、「 MongoDB パフォーマンスのベストプラクティス ガイド 」をお読みください。
パフォーマンスに関するベストプラクティスを実装しても遅延が発生する場合は、接続設定を変更して接続プールのサイズを増やすことができます。 接続プールは、ドライバーが常に維持するサーバーへの接続のグループです。
接続プールの最大サイズを指定するには、 MongoClient
インスタンスの接続オプションでmaxPoolSize
オプションを設定します。 maxPoolSize
のデフォルト値は100
です。 サーバーへの使用中の接続数がmaxPoolSize
に達した場合、ドライバーへの接続が利用可能になるまでサーバーに送信される次の操作は一時停止します。 次のコードでは、新しいMongoClient
を作成するときに、 maxPoolSize
を150
に設定します。
const client = new MongoClient(uri, { maxPoolSize: 150 });
Tip
接続プーリングの詳細については、 「 ノード ドライバーで接続プーリングがどのように機能するか 」を参照してください。 FAQ エントリー
接続stringがレプリカセットで有効であることを確認するには
ドライバーに渡される接続stringでは、レプリカセット構成で設定されているサーバーの正確なホスト名を使用する必要があります。 レプリカセットが次の構成設定にある場合、レプリカセットの検出とフェイルオーバーを機能させるには、ドライバーはserver1
、 server2
、およびserver3
にアクセスする必要があります。
{ "_id": "testSet", "version": 1, "protocolVersion": 1, "members": [ { "_id": 1, "host": "server1:31000" }, { "_id": 2, "host": "server2:31001" }, { "_id": 3, "host": "server3:31002" } ] }
ここで質問の回答が見つからない場合は、「問題とヘルプ 」セクションに記載されているフォーラムとサポート チャネルをお試しください。