PhpRiot
News Archive
PhpRiot Newsletter
Your Email Address:

More information

Connection Handling with the MongoDB PHP driver

Note: This article was originally published at Planet PHP on 4 December 2012.
Planet PHP

Connection Handling with the MongoDB PHP driver

London, UK Tuesday, December 4th 2012, 09:07 GMT

The 1.3 release series of the PHP MongoDB driver features a rewritten connection handling library. This is quite a large change and changes how the PHP driver deals with persistent connections and connection pooling.

Connections in the 1.2 series

The 1.2 release introduced connection pooling into the driver. This means that any time the driver needs to use a connection to run queries, it would request a connection from the pool. It would then later return the connection once it was done with it. Being done is defined as "the variable holding the connection object goes out of scope". To illustrate that, take for example the following scripts.

The simplest version:

demo-test; $c-insert(array('test' = 'yes')); ? a connection is returned to the pool as $m goes out of scope

Inside a function:

demo-test; $c-insert(array('test' = 'yes')); } // a connection is returned to the pool as $m goes out of scope ?

Now, in a few cases, this can result in lots of connections being made. One common occurence is trying to use connections deep inside a model layer-which typically happens if you use ORMs/ODMs with complex structures having a link to your connection object. A simple variant of how this happens is:

Connections in the 1.3 series

In the 1.3 series the connection management is done different. Per worker process (thread or PHP-FPM or Apache worker) the driver now manages connections in the C-part of driver separately from the Mongo* objects. This greatly reduces complexity in the driver. Let's have a look at how the driver handles connection for a basic MongoDB setups with just one node.

When a worker process starts up, the MongoDB driver instantiates a manager to manage your connections. By default of course, this manager is rather sad, as it contains no connections yet.

Upon the first request doing new MongoClient();, the driver creates a new connection, and with this connection it creates a hash to identify this connection. Parameters for this hash includes: the hostname and the port, the process ID (pid), if available the replica set name and in case of authenticated connections, the database name, the username and a hash of the password. We will come back to authenticated connections later. You can quite easily see which hash is created, by calling the MongoClient::getConnections() method:

getConnections()[0]['hash']); ?

Which outputs:

string(22) "whisky:27017;-;X;22835"

The - in this output denotes that the connection does not belong to a replica set and the X in this output is a place holder in case no username, database and password are given. 22835 is the process ID of the running script.

This newly created connection is then registered with the manager:

Any time a connection is needed, for either an insert, delete, update, find or command query, the driver asks the manager to find a fitting connection to perform this query. It uses the information from the arguments to new MongoClient() as well as the PID of the current process to find this connection. Because the manager has a connection list per worker process/thread, and PHP's workers all run one request at a time, there is no need to have more than one connection per host. The connection gets reused and reused until the PHP worker ends, or you close the connection

Truncated by Planet PHP, read more at the original (another 8300 bytes)