マニュアル
PHP Manual

接続

MongoDB への接続は単に new Mongo とするだけの簡単なものですが、 オプションや設定項目が多数あります。 Mongo::__construct() のページにすべての API オプションをまとめましたが、ここではより実用的な使用例とアドバイスをとりあげます。

接続時のログイン

MongoDB を --auth あるいは --keyFile オプションつきで起動すると、 まずログインしないとドライバを使った操作ができなくなります。 接続にログインするには、ユーザー名とパスワードを接続 URI に指定します。

<?php

$m 
= new Mongo("mongodb://${username}:${password}@localhost");

?>

接続が落ちると、ドライバが自動的に再接続と再認証を試みます。

データベースレベルでの認証には MongoDB::authenticate() を使います。

<?php

$m 
= new Mongo();
$db $m->admin;

$db->authenticate($username$password);

?>

この方式には大きな問題があります。データベース接続が落ちて再接続したときには、 新しい接続はまだ認証されていない状態になるということです。 URI 形式を使えば、新しい接続が立ち上がったときに PHP ドライバが自動的に認証を試みます。

別のデータベースに対して認証を試みるには、データベース名をホスト名の後に指定します。 この例では、"blog" データベースにログインしています。

<?php

$m 
= new Mongo("mongodb://${username}:${password}@localhost/blog");

?>

レプリカセット

レプリカセットに接続するには、セットに属するサーバーをひとつ以上指定して、 さらに replicaSet オプションを使います。

<?php

$m 
= new Mongo("mongodb://localhost:27017", array("replicaSet" => "myReplSetName"));

?>

バージョン 1.0.9 以降のドライバでは、レプリカセットへの接続が必須となります (それより前のバージョンでは、マスタの自動検出や再接続が正しく動作しません)。

PHP ドライバは、指定したサーバー群に問い合わせてどれがマスタなのかを調べます。 リストにあげたサーバーのうち少なくともひとつに接続でき、 マスタが見つかってさえいれば接続が成功したとみなされます。 どのサーバーにも接続できない、あるいはマスタが見つからないといった場合は MongoConnectionException がスローされます。

マスタが使えなくなったときに、スレーブがマスタになるには数秒かかります。 その間は、この接続では一切のデータベース操作ができなくなります (スレーブに接続して読み込みを行うことは可能です)。 したがって、このときに何らかの読み書き操作をすると例外が発生します。

新しいマスタが選ばれると、読み込みや書き込みの操作時にドライバが新しいマスタを検出できるようになります。 そして、ドライバがデータベース接続を切り替えて通常の操作を続行できるようになります。

レプリカセットについての詳細は、 » コアドキュメント を参照ください。

ドメインソケットのサポート

MongoDB をローカルで動かしていてバージョン 1.0.9 以降のドライバを使っている場合は、ファイル経由でデータベースに接続することができます。 MongoDB は、起動時に自動的にソケットファイル /tmp/mongodb-<port>.sock をオープンします。

ソケットファイルに接続するには、このパスを MongoDB 接続文字列に指定します。

<?php

$m 
= new Mongo("mongodb:///tmp/mongo-27017.sock");

?>

上で示したようなソケットファイルへの接続で認証を使いたい場合は、 ポート番号 0 を指定しなければなりません。 接続文字列のパーサは、これを接続文字列の終端と見なします。

<?php

$m 
= new Mongo("mongodb://username:password@/tmp/mongo-27017.sock:0/foo");

?>

接続プーリング (バージョン 1.2.0 以降)

接続の作成は、ドライバが行う作業の中でも最も重量級の作業です。 接続を正しく確立するには、どんなに高速なネットワークであっても数百ミリ秒はかかることがあります。 そこで、ドライバが新たな接続を作る回数をできるだけ減らすために、 プールにある接続を再利用することを考えます。

ユーザーが新しい Mongo のインスタンスを作ると、 必要な接続はすべて接続プールから取り出します (レプリカセットへの接続には 複数の接続が必要となることもあります。それぞれが、セット内の個々のメンバーへの接続となります)。 Mongo のインスタンスがスコープ外に出ると、接続をプールに返します。 PHP のプロセスが終了すると、プール内のすべての接続が閉じられます。

"なぜこんなに接続をオープンしてしまっているの?"

接続プールが作成する接続の数が大量になることがあります。 これは意外なことではなく、ちょっとした計算をすればどれだけの接続が必要になるかがわかります。 接続の総数に影響するのは、次の三要素です。

  • connections_per_pool

    各接続プールが作成する接続の数は、デフォルトでは無制限です。 これは問題だと感じる人もいるでしょう。無制限に作れるとしても、 ファイルディスクリプタの制限があるから何千も作るのは無理じゃないか? と。 実際のところ、そこまで達することはあり得ません。 未使用の接続はプールに返されてその後再利用されるので、 後から接続を利用するときには新しく作るのではなく既存の接続を使います。 何千もの接続を一気に作ってどれもスコープから外れないようにでもしない限り、 接続の数は常識的な範囲に収まります。

    プール内の接続数を知るには MongoPool::info() を使います。 指定したサーバーの "in use" フィールドと "in pool" フィールドの値を足した結果が、 そのプールの接続の総数となります。

  • pools_per_process

    接続先の MongoDB サーバーごとに、自前の接続プールを持っています。 たとえばローカルのホスト名が "example.net" のときに "example.net:27017"、"localhost:27017"、そして "/tmp/mongodb-27017.sock" に接続すると、全部で 3 つの接続プールができることになります。 開いている接続プールの総数は MongoPool::info() で取得できます。

  • processes

    PHP のプロセスごとに、プール群は分かれています。 PHP-FPM や Apache は、一般的に 6 から数十の間の PHP ワーカープロセスを作ります。最大でどれだけの PHP プロセスが立ち上がる設定になっているか、確認しましょう。

    PHP-FPM を使っている場合は、接続数の見積もりは多少面倒です。 というのも、負荷が高くなると PHP-FPM ワーカーをより多く立ち上げるようになるからです。 安全側に倒すなら、max_children パラメータあるいは spare_servers+start_servers (のどちらか大きいほう) を確認しましょう。これが、想定すべき PHP プロセス数 (そして、プール数) となります。

これら 3 つの変数を掛け合わせた connections_per_pool*pools_per_process*processes で、接続の総数が得られます。connections_per_pool はプールによって異なることに注意しましょう。つまり、この計算をするときには connections_per_pool は最大値を使わなければなりません。

たとえば、プールごとに 30 の接続があって PHP のプロセスあたり 10 のプールを用意し、 さらに PHP が 128 プロセスあるものとします。この場合、マシン上での接続数は 38400 になります。したがって、これだけの数をさばける程度にファイルディスクリプタの制限を増やしておく必要があります。 ファイルディスクリプタの上限に達してしまうと、それ以上の接続は処理できなくなります。

接続プーリングに関する詳細な情報は MongoPool を参照ください。

持続的接続

注意:

この節は 1.2.0 以降のバージョンには関係ありません。 1.2.0 以降、接続は常に持続的なものとなり、 ドライバが自動管理するようになりました。 プーリングに関する詳細な情報は MongoPool を参照ください。

データベースへの接続を新たに確立させるには、非常に時間がかかります。 データベースへ接続の作成回数を最小限にするには、持続的接続を使うことができます。 持続的接続は PHP が保持するので、同じ接続を使って複数のリクエストを送ることができます。

たとえば、この単純なプログラムはデータベースに 1000 回接続します。

<?php

for ($i=0$i<1000$i++) {
  
$m = new Mongo();
}

?>

実行時間は約 18 秒です。これを、持続的接続を使うように変更してみましょう。

<?php

for ($i=0$i<1000$i++) {
  
$m = new Mongo("localhost:27017", array("persist" => "x"));
}

?>

実行時間は .02 秒未満になりました。データベースへの接続は 1 回だけしか行わないからです。

持続的接続には識別用の文字列 (上の例では "x") が必要で、これを使って接続を識別します。 持続的接続を使うには、ホスト名とポート、持続文字列、そしてユーザー名とパスワード(指定した場合) が既存の持続的接続と一致しなければなりません。 一致しない場合は、この識別情報で新しい接続を作成します。

持続的接続を使うことを強く推奨します。 実運用環境では、やむを得ぬ理由がない限り常に持続的接続を使うべきです。 リレーショナルデータベースにおいて持続的接続を推奨しない理由はいくつかありますが、 その大半は MongoDB には無関係なものです。


マニュアル
PHP Manual