Is there documentation on MongoDB\Client's connection persistence behavior?

I’m encountering a problem where PHP code (using v1.6 of the PHP MongoDB library) is quickly hitting the 1.5k simultaneous-connection limit on my M10 account. Upon further inspection, it looks like it’s possible failing to reuse old connections and also failing to close connections, as when I do a graceful restart of Apache to make it close all of the inactive threads it suddenly drops all of the Mongo connections it was holding open.

I’ve done a fair amount of research trying to figure out what’s going on behind the scenes here, connection-wise. I found a bunch of documentation for the old MongoClient class talking about its connection persistence mechanisms (such as the official documentation or this article), but thus far I’ve been completely unable to locate any similar documentation for the newer MongoDB\Client library. Is there any documentation available on how the new library handles its connection persistence?

Specifically, I’d love it if there were a way to see whether any given MongoDB\Client instance is creating a new connection or reusing an old one. I found this pull request to the PHP MongoDB driver that should allow the persistence function to be turned off in the future, but that’s still a ways out.

Does anyone have any experience with this issue?

The PHP driver reuses connections as explained in the PHP extension’s Connection handling and persistence documentation. Within a single PHP process, multiple MongoDB\Driver\Manager instances reuse the same client object if the constructor arguments of the managers are the same. These connections are kept open until the process terminates, but since they are reused there shouldn’t be an ever-growing number of connections unless you prevent reuse of clients. One way this could happen is by creating each MongoDB\Client instance with different parameters (e.g., attaching a random key to either options arrays), which leads to each manager instance creating a new internal client that holds connections.

The specifics of connections obviously depend on your code, but also on the environment that you deployed your application in. Obviously, separate PHP processes (e.g. those spawned by php-fpm) can’t share client objects. This means that if you run php-fpm with 20 processes and send a single request to each of them, there will be 20 clients that hold connections to the cluster.

The PR you linked to disable persistence has been merged, but we don’t advise enabling this flag unless you encounter serious issues. One reason for reusing internal clients is that this reduces the performance impact of discovering and connecting to the cluster when sending multiple requests to a single PHP process (as is typical when running php-fpm behind a web server).

To better evaluate what’s happening here, some numbers would be interesting: in the entire deployment, how many PHP processes connect to the cluster? Elaborating on the example above, having 20 web servers running 20 php processes to handle requests would mean that at least 400 clients will be created and connect to MongoDB - you can see how quickly this could reach 1500 clients depending on your deployment.
Furthermore, do you see connections rise slowly to this 1500 connection limit or do you immediately run into the limit?

If you feel confident, you can test the feature of disabling persistent clients by manually compiling the extension and enabling the flag. Since this is pre-release software, be aware that there could be negative performance impacts due to this change, so I don’t recommend running this version in a production environment. With the change, you should see the number of connections drop as they are dropped when a request terminates, but I’ll point out that this could come at the expense of performance when connecting to the same cluster in a subsequent request.

2 Likes