Docs Menu
Docs Home
/ / /
Node.js

FAQ

項目一覧

  • MongoDB への接続中にエラーが発生するのはなぜですか?
  • ノード ドライバーでの接続プーリングの仕組み
  • "connectTimeoutMS"、"socketTimeoutMS"、"maxTimeMS" の違いは何ですか。
  • クライアントが切断した場合、操作の実行はどうなりますか。
  • ドライバーが使用できないソケットを閉じたことを確認するには
  • ソケットがアクティブになる前にタイムアウトしないようにするにはどうすればよいですか。
  • "connectTimeoutMS" と "socketTimeoutMS" の値が "0" とは何ですか。
  • 長時間実行される操作によるサーバーの速度低下を防ぐ方法
  • "keepAlive" 設定はどのような操作をしますか。
  • 予期しないネットワーク動作が発生している場合は
  • 低速操作による他の操作の遅延を防ぐには
  • 接続stringがレプリカセットで有効であることを確認するには

このページには、よくある質問とその回答が含まれています。

Tip

このページで問題の解決策が見つからない場合は、次のステップやその他のリソースについて問題とヘルプページを参照してください。

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()を呼び出すと非アクティブなソケットのみが閉じられるため、このメソッドを使用して実行中の操作を中断したり終了したりすることはできません。 ドライバーはこれらのソケットを、プロセスが完了した場合にのみ閉じます。

設定
説明
connectTimeoutMS

connectTimeoutMS は、接続プールからの個々の接続がタイムアウトする前に MongoDB サーバーへの TCP 接続を確立するための時間をミリ秒単位で設定する接続オプションです。

Tip

MongoClient.connect の許可された時間を変更するには MongoDB サーバーへの接続を確立するには、代わりにserverSelectionTimeoutMS オプションを使用します。

デフォルト: 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に設定すると、アプリケーションはオペレーティング システムのデフォルトのソケット タイムアウト値を使用します。

タイムアウト値を指定することで、実行時間が長い操作によってサーバーが低速になるのを防ぐことができます。 maxTimeMS()メソッドをCursorを返す操作に連鎖させて、特定のアクションにタイムアウトを設定できます。

次の例えは、 maxTimeMS()メソッドをCursorを返す操作に連結する方法を示しています。

// Execute a find command
await collection
.find({ $where: "sleep(100) || true" })
.maxTimeMS(50);

keepAlive は、connection-setting TLS keepAlive を開始する前に待機するミリ秒数を設定する です TCP ソケット上。keepAliveオプションは、MongoDB に定期的に検証を送信することでソケットを有効にします。 ただし、オペレーティング システムがSO_KEEPALIVEをサポートしている場合にのみ機能します。

この設定は Node.js ドライバーの v5.3 以降では非推奨です。

警告

ファイアウォールが keepAlive パケットを無視または削除した場合、これは機能しない可能性があります。

アプリケーション サーバーと MongoDB の間に存在する内部ファイアウォールは、多くの場合誤って構成され、ソケット接続の削除が必要以上に実行されています。

予期しないネットワーク動作が発生した場合は、以下の点を確認してください。

  1. ファイアウォールはソケットを閉じるときにFIN packetを送信し、ドライバーがソケットが閉じられたことを検出できるようにします。

  2. ファイアウォールはkeepAlive検証を許可する必要があります。

同じMongoClientインスタンスを使用して複数の MongoDB 操作を同時に実行すると、低速操作によって他の操作が遅れる可能性があります。 遅い操作では MongoDB への接続が専有され続け、そのため、追加の接続が利用可能になるまで他の操作が待機する恐れがあります。

MongoDB の低速操作が遅延の原因になっていると思われる場合は、次の方法を使用して、進行中のすべての操作のパフォーマンスを確認できます。

遅延の原因となっている操作を特定したら、これらの操作のパフォーマンスを向上させるようにしてください。 可能な解決策については、「 MongoDB パフォーマンスのベストプラクティス ガイド 」をお読みください。

パフォーマンスに関するベストプラクティスを実装しても遅延が発生する場合は、接続設定を変更して接続プールのサイズを増やすことができます。 接続プールは、ドライバーが常に維持するサーバーへの接続のグループです。

接続プールの最大サイズを指定するには、 MongoClientインスタンスの接続オプションmaxPoolSizeオプションを設定します。 maxPoolSizeのデフォルト値は100です。 サーバーへの使用中の接続数がmaxPoolSizeに達した場合、ドライバーへの接続が利用可能になるまでサーバーに送信される次の操作は一時停止します。 次のコードでは、新しいMongoClientを作成するときに、 maxPoolSize150に設定します。

const client = new MongoClient(uri, { maxPoolSize: 150 });

Tip

接続プーリングの詳細については、 「 ノード ドライバーで接続プーリングがどのように機能するか 」を参照してください。 FAQ エントリー

ドライバーに渡される接続stringでは、レプリカセット構成で設定されているサーバーの正確なホスト名を使用する必要があります。 レプリカセットが次の構成設定にある場合、レプリカセットの検出とフェイルオーバーを機能させるには、ドライバーはserver1server2 、およびserver3にアクセスする必要があります。

{
"_id": "testSet",
"version": 1,
"protocolVersion": 1,
"members": [
{
"_id": 1,
"host": "server1:31000"
},
{
"_id": 2,
"host": "server2:31001"
},
{
"_id": 3,
"host": "server3:31002"
}
]
}

ここで質問の回答が見つからない場合は、「問題とヘルプ 」セクションに記載されているフォーラムとサポート チャネルをお試しください。

戻る

複数フィールド結合