There is an article widely circulated on the Internet about the difference between memcache and memcached, the two extension modules of PHP. It specifically emphasizes that a big difference between memcached and memcached is that the memcached module does not support long connections. So for many years I thought that memcached did not support long connections. In fact, this is not the case. The memcached extension module has supported long connections since a very early version. We can see from the source code of the extension module:
/* {{{ Memcached::__construct([string persistent_id[, callback on_new[, string connection_str]]]))
Creates a Memcached object, optionally using persistent memcache connection */
static PHP_METHOD(Memcached, __construct)
{
From the PHP manual, we can see that the constructor provided by the memcached extension module provides an optional parameter persistent_id
, which is introduced in the manual:
By default, Memcached instances will be destroyed after the request ends. However, you can share instances between requests by specifying a unique ID for each instance by persistent_id
when creating it. All instances created with the same persistent_id
value share the same connection.
The meaning of this parameter is that if you pass a named id to the constructor, then a long connection will be established. Usually we use PHP-FPM mode, so that the PHP-FPM process will resume the memcached service A long connection channel. We can also understand that persistent_id is a connection pool name, and all php-fpm processes are members of this connection pool.
But what we need to pay attention to is that PHP is an interpreted language. When PHP establishes a long connection through the memached module for the first time, remember that subsequent PHP executions should not build long connections named with the same persistent_id through the constructor of memcached. Long connections with different persistent_id names can be established. If the same name is executed repeatedly by PHP, it will definitely cause the php-fpm process to be abnormal and cause the communication with memcached to become slower and slower. At the same time, depending on the version of libmemcached, it will also cause PHP to generate coredump. .
So how do we prevent a single php-fpm from repeatedly establishing a long connection after establishing a long connection named with persistent_id? In fact, it is explained in the PHP manual with comments, and the content is as follows:
When using persistent connections, it is important to not re-add servers.
This is what you do not want to do:
$mc = new Memcached('mc'); $mc->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true); $mc->addServers(array( array('mc1.example.com',11211), array('mc2.example.com',11211), ));
Every time the page is loaded those servers will be appended to the list resulting in many simultaneous open connections to the same server. The addServer/addServers functions to not check for existing references to the specified servers.
A better approach is something like:
$mc = new Memcached('mc'); $mc->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true); if (!count($mc->getServerList())) { $mc->addServers(array( array('mc1.example.com',11211), array('mc2.example.com',11211), )); }<br />
Use the getServerList() method to check whether a long connection resource with the same name already exists in the php-fpm process container currently used for execution. If it exists, do not repeatedly use the addServers() method to add a new connection configuration.