MongoDB C ドライバーには、シングルスレッドとプールの 2 つの接続モードがあります。 シングルスレッド モードは、PHP などの言語にドライバーを埋め込むために最適化されています。 マルチスレッド プログラムでは、プール モードを使用する必要があります。このモードでは合計接続数が最小限に抑えられ、プール モードではバックグラウンド スレッドが MongoDB サーバーのトポロジーを監視するため、プログラムはそれをスキャンするためにブロックする必要がありません。
シングル モード
シングルモードでは、プログラムは mongoc_client_t を直接作成します。
mongoc_client_t *client = mongoc_client_new ( "mongodb://hostA,hostB/?replicaSet=my_rs");
クライアントは、プログラムが MongoDB 操作に最初に使用するときにオンデマンドで接続します。 サーバーごとに非ブロッキング ソケットを使用して、各サーバーのチェックを同時に開始し、非同期の poll
またはselect
関数を使用して、すべてのサーバーが応答またはタイムアウトするまでソケットからイベントを受信します。 別の方法では、シングルスレッド モードでは、C ドライバーが関数を使用してすべてのチェックを同時に開始し、すべてのチェックが完了またはタイムアウトすると を関数します。 スキャンが完了すると、クライアントはプログラムの操作を実行し、返します。
単一モードでは、クライアントはサーバートポロジーを約 1 分ごとに再スキャンします。前回のスキャンから 1 分以上経過した場合、クライアントがスキャンを完了している間、クライアントに対する次の操作はブロックされます。この間隔は接続文字列の heartbeatFrequencyMS
で設定できます。 (mongoc_uri_t を参照してください。)
単一のクライアントは、トポロジー内のサーバーごとに 1 つの接続を開きます。これらの接続は、トポロジーのスキャンと通常の操作の実行の両方に使用されます。
プール モード
プールモードを有効にするには、mongoc_client_pool_t: を作成します。
mongoc_uri_t *uri = mongoc_uri_new ( "mongodb://hostA,hostB/?replicaSet=my_rs"); mongoc_client_pool_t *pool = mongoc_client_pool_new (uri);
プログラムが最初にmongoc_client_pool_popを呼び出すと、プールはバックグラウンドで監視スレッドを起動します。監視スレッドは、 接続文字列内のすべてのサーバーに独立して接続します。 モニタリング スレッドがサーバーから hello 応答を受け取ると、サーバートポロジーの共有ビューが更新されます。新しいサーバーが検出されると、追加の監視スレッドと接続が作成されます。モニタリング スレッドは、サーバートポロジーの共有ビューからサーバーが削除されると終了します。
MongoDB 操作を実行する各スレッドは、 プールからクライアントをチェックアウトする必要があります。
mongoc_client_t *client = mongoc_client_pool_pop (pool); /* use the client for operations ... */ mongoc_client_pool_push (pool, client);
mongoc_client_tオブジェクトはスレッドセーフではありませんが、mongoc_client_pool_tのみがスレッドセーフです。
ドライバーがプール モードの場合、モニタリングで使用可能なサーバーが検出されるとすぐに、プログラムの操作のブロックは解除されます。 たとえば、プログラム内のあるスレッドがプライマリで「挿入」を実行するのを待機している場合、すべてのセカンダリもチェックされるのを待つのではなく、プライマリが検出されるとすぐにブロックが解除されます。
プールは監視のためにサーバーごとに 1 つの接続を開き、各クライアントはアプリケーション操作に使用する各サーバーに独自の接続を開きます。バックグラウンド モニタリング スレッドは、ほぼ 10 秒ごとにサーバーを個別に再スキャンします。この間隔は接続文字列の heartbeatFrequencyMS
で設定できます。 (mongoc_uri_t を参照してください。)
接続文字列にwaitQueueTimeoutMS
を指定して、mongoc_client_Pool_pop がプールからのクライアントを待機する時間を制限することもできます。(mongoc_uri_t を参照してください。)waitQueueTimeoutMS
が指定されている場合は、クライアントが実際に返されたことを確認する必要があります。
mongoc_uri_t *uri = mongoc_uri_new ( "mongodb://hostA,hostB/?replicaSet=my_rs&waitQueueTimeoutMS=1000"); mongoc_client_pool_t *pool = mongoc_client_pool_new (uri); mongoc_client_t *client = mongoc_client_pool_pop (pool); if (client) { /* use the client for operations ... */ mongoc_client_pool_push (pool, client); } else { /* take appropriate action for a timeout */ }
プールのサイズと動作を構成するには接続プールオプション を参照してください。プールモードでドライバーを使用するマルチスレッド プログラムの拡張例については、 mongoc_client_Pool_t を参照してください。