php-doc-en/reference/mongo/connecting.xml

360 lines
12 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<section xml:id="mongo.connecting" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Connecting</title>
<para>
Connecting to MongoDB can be as easy as <literal>new Mongo</literal>, but
there are many additional options and configurations. The
<function>Mongo::__construct</function> page covers all of the API options,
but this page gives some more details and advice for practical use cases.
</para>
<section>
<title>Authentication</title>
<para>
If MongoDB is started with the <literal>--auth</literal> or
<literal>--keyFile</literal> options, you must authenticate before you can do
any operations with the driver. You may authenticate a connection by
specifying the username and password in either the connection URI or the
<literal>"username"</literal> and <literal>"password"</literal> options for
<function>Mongo::__construct</function>.
</para>
<programlisting role="php">
<![CDATA[
<?php
// Specifying the username and password in the connection URI
$m = new Mongo("mongodb://${username}:${password}@localhost");
// Specifying the username and password via the options array
$m = new Mongo("mongodb://localhost", array("username" => $username, "password" => $password));
?>
]]>
</programlisting>
<para>
By default, the driver will authenticate against the <literal>admin</literal>
database. You may authenticate against a different database by specifying it
in either the connection URI or the <literal>"db"</literal> option for
<function>Mongo::__construct</function>.
</para>
<programlisting role="php">
<![CDATA[
<?php
// Specifying the authentication database in the connection URI
$m = new Mongo("mongodb://${username}:${password}@localhost/myDatabase");
// Specifying the authentication database via the options array
$m = new Mongo("mongodb://${username}:${password}@localhost", array("db" => "myDatabase"));
?>
]]>
</programlisting>
<para>
If your connection is dropped, the driver will automatically attempt to
reconnect and reauthenticate you.
</para>
</section>
<section>
<title>Replica Sets</title>
<para>
To connect to a replica set, specify one or more members of the set and use
the <literal>replicaSet</literal> option. Multiple servers may be delimited
by a comma.
</para>
<programlisting role="php">
<![CDATA[
<?php
// Using one server as the seed list
$m = new Mongo("mongodb://rs1.example.com:27017", array("replicaSet" => "myReplSetName"));
// Using multiple servers as the seed list
$m = new Mongo("mongodb://rs1.example.com:27017,rs2.example.com:27017", array("replicaSet" => "myReplSetName"));
?>
]]>
</programlisting>
<para>
Version 1.0.9+ of the driver is required to connect to a replica set
(earlier versions of the driver will not autodetect the master or reconnect
correctly).
</para>
<para>
The PHP driver will query the database server(s) listed to figure out who is
master. So long as it can connect to at least one host listed and find a
master, the connection will succeed. If it cannot make a connection to any
servers listed or cannot find a master, a
<classname>MongoConnectionException</classname> will be thrown.
</para>
<para>
If the master becomes unavailable, the slaves will not promote a new master
for a few seconds. During that time, this connection will not be able to
perform any database operations (connections to slaves will still be able to
perform reads). Thus, if you attempt to do any sort of read or write on this
connection, it will throw an exception.
</para>
<para>
Once a master is elected, attempting to perform a read or write will allow
the driver to detect the new master. The driver will make this its primary
database connection and continue operating normally.
</para>
<para>
For more information on replica sets, see the
<link xlink:href="&url.mongodb.replica;">core documentation</link>.
</para>
</section>
<section>
<title>Sharding</title>
<para>
To connect to a shard cluster, specify the address of one or more
<literal>mongos</literal> instances in the connection string. Multiple
servers may be delimited by a comma.
</para>
<programlisting role="php">
<![CDATA[
<?php
// Using one server as the seed list
$m = new Mongo("mongodb://mongos1.example.com:27017");
// Using multiple servers as the seed list
$m = new Mongo("mongodb://mongos1.example.com:27017,mongos2.example.com:27017"));
?>
]]>
</programlisting>
<para>
Regardless of whether each shard is a stand-alone <literal>mongod</literal>
server or a full replica set, the driver's connection process is the same.
All database communication will be routed through <literal>mongos</literal>.
</para>
<para>
For more information on sharding with MongoDB, see the
<link xlink:href="&url.mongodb.docs.sharding;">sharding documentation</link>.
</para>
</section>
<section>
<title>Domain Socket Support</title>
<para>
If you are running MongoDB locally and using version 1.0.9+ of the driver,
you can connect to the database via file. MongoDB automatically opens a
socket file on startup: <literal>/tmp/mongodb-&lt;port&gt;.sock.</literal>
</para>
<para>
To connect to the socket file, specify the path in your MongoDB connection
string:
</para>
<programlisting role="php">
<![CDATA[
<?php
$m = new Mongo("mongodb:///tmp/mongo-27017.sock");
?>
]]>
</programlisting>
<para>
If you would like to use authentication on connection (as described above)
with a socket file, you must specify a port of 0 so that the connection
string parser knows where the end of the connection string is.
</para>
<programlisting role="php">
<![CDATA[
<?php
$m = new Mongo("mongodb://username:password@/tmp/mongo-27017.sock:0/foo");
?>
]]>
</programlisting>
</section>
<section>
<title>Connection Pooling (version 1.2.0+)</title>
<para>
Creating connections is one of the most heavyweight things that the driver
does. It can take hundreds of milliseconds to set up a connection correctly,
even on a fast network. Thus, the driver tries to minimize the number of new
connections created by reusing connections from a pool.
</para>
<para>
When a user creates a new instance of <classname>Mongo</classname>, all
necessary connections will be taken from their pools (replica sets may
require multple connections, one for each member of the set). When the
<classname>Mongo</classname> instance goes out of scope, the connections will
be returned to the pool. When the PHP process exits, all connections in the
pools will be closed.
</para>
<section>
<title>"Why do I have so many open connections?"</title>
<para>
Connection pools can generate a large number of connections. This is expected
and, using a little arithmetic, you can figure out how many connections to
expect. There are three factors in the total number of connections:
</para>
<itemizedlist>
<listitem>
<para>
<literal>
connections_per_pool
</literal>
</para>
<para>
Each connection pool will create, by default, an unlimited number of
connections. One might assume that this is a problem: if it can create an
unlimited number of connections, couldn't it create thousands and the
server would run out of file descriptors? In practice, this is unlikely,
as unused connections are returned to the pool to be used later, so future
connections will use the same connection instead of creating a new one.
Unless you create thousands of connections at once without letting any go
out of scope, the number of connections open should stay at a reasonable
number.
</para>
<para>
You can see how many connections you have in a pool using the
<function>MongoPool::info</function> function. Add up the "in use" and
"in pool" fields for a given server. That is the total number of
connections for that pool.
</para>
</listitem>
<listitem>
<para>
<literal>
pools_per_process
</literal>
</para>
<para>
Each MongoDB server address you're connecting to gets its own connection
pool. For example, if your local hostname is "example.net", connecting
to "example.net:27017", "localhost:27017", and "/tmp/mongodb-27017.sock"
will create three connection pools. You can see how many connection pools
you have open using <function>MongoPool::info</function>.
</para>
</listitem>
<listitem>
<para>
<literal>
processes
</literal>
</para>
<para>
Each PHP process has a separate set of pools. PHP-FPM and Apache
generally create between 6 and a couple dozen PHP worker children. Check
your settings to see what the max number of PHP processes is that can be
spawned.
</para>
<para>
If you are using PHP-FPM, estimating the number of connections can be
tricky because it will spawn more PHP-FPM workers under heavy load. To be
on the safe side, look at the max_children parameter or add up
spare_servers+start_servers (choose whichever number is higher). That's
how many PHP processes (and, thus sets of pools) you should plan for.
</para>
</listitem>
</itemizedlist>
<para>
The three variables above can be multiplied together to give the max
number of connections expected:
<literal>connections_per_pool*pools_per_process*processes</literal>. Note
that <literal>connections_per_pool</literal> can be different for different
pools, so <literal>connections_per_pool</literal> should be the max.
</para>
<para>
For example, suppose we're getting 30 connections per pool, 10 pools per PHP
process, and 128 PHP processes. Then we can expect 38400 connections from
this machine. Thus, we should set this machine's file descriptor limit to
be high enough to handle all of these connections or it may run out of file
descriptors.
</para>
<para>
See <classname>MongoPool</classname> for more information on connection
pooling.
</para>
</section>
</section>
<section>
<title>Persistent Connections</title>
<note>
<para>
This section is not relevant for 1.2.0+. In 1.2.0+, connections are always
persistent and managed automatically by the driver. See
<classname>MongoPool</classname> for more information on pooling.
</para>
</note>
<para>
Creating new connection to the database is very slow. To minimize the number
of connections that you need to make, you can use persistent connections. A
persistent connection is saved by PHP, so you can use the same connection for
multiple requests.
</para>
<para>
For example, this simple program connects to the database 1000 times:
</para>
<programlisting role="php">
<![CDATA[
<?php
for ($i=0; $i<1000; $i++) {
$m = new Mongo();
}
?>
]]>
</programlisting>
<para>
It takes approximately 18 seconds to execute. If we change it to use a
persistent connection:
</para>
<programlisting role="php">
<![CDATA[
<?php
for ($i=0; $i<1000; $i++) {
$m = new Mongo("localhost:27017", array("persist" => "x"));
}
?>
]]>
</programlisting>
<para>
...it takes less than .02 seconds to execute, as it only makes one database
connection.
</para>
<para>
Persistent connections need an identifier string (which is "x" in the above
example) to uniquely identify them. For a persistent connection to be used,
the hostname, port, persist string, and username and password (if given) must
match an existing persistent connection. Otherwise, a new connection will be
created with this identifying information.
</para>
<para>
Persistent connections are <emphasis>highly recommended</emphasis> and should
always be used in production unless there is a compelling reason not to.
Most of the reasons that they are not recommended for relational databases
are irrelevant to MongoDB.
</para>
</section>
</section>