edit-icon download-icon

Improve ApsaraDB for Memcache performance through PHP persistent connections

Last Updated: Dec 20, 2017

Problem description

Some PHP users experienced that the performance of ApsaraDB for Memcache fails to meet the expected indexes through tests. We followed up on the situation and found that most users go through the Apache web service to connect to ApsaraDB for Memcache through PHP, using short connections. The overhead of every short connection not only includes socket reconnection, but also complicated re-authentication procedures, being much larger than that of a general request. This impacts the website efficiency greatly.

Solution

We recommend users change short connections to persistent connections. But ApsaraDB for Memcache requires the use of PHP Memcached extensions which do not possess the pconnect interface as memcache extensions do. Following is a tutorial on how to establish persistent connections in PHP, for your reference.

On the PHP official website, the introduction of memcached constructor includes the following:

  1. Note:
  2. Memcached::__construct ([ string $persistent_id ] ): Create a Memcached instance representing the connection to the Memcached service end.
  3. Parameter
  4. Persistent_id: By default, the Memcached instance is destroyed after the request is over. But you can specify a unique ID for every instance through the persistent_id at the instance creation to share the instance between requests. All the instances created using the same persistent_id share the same connection.

That is, you must pass an identical persistent_id to the constructor called to achieve shared connections. The code implementation is as follows:

  1. <?php
  2. $memc = new Memcached(‘ocs’);//ocs refers to persistent_id
  3. if (count($memc->getServerList()) == 0) /*Before establishing the connection, first judge*/
  4. {
  5. echo "New connection"."<br>";
  6. /*All options must be included in the evaluation, because some options may lead to reconnection, or cause a persistent connection to become a short connection.*/
  7. $memc->setOption(Memcached::OPT_COMPRESSION, false);
  8. $memc->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
  9. $memc->setOption(Memcached::OPT_TCP_NODELAY, true); //Important: The php memcached has a bug that when the get value does not exist, there is a fixed 40 ms of latency. Enabling this parameter can avoid this bug.
  10. /* The addServer code must be included in the evaluation, otherwise it is equal to repeating the establishment of the ‘ocs’ connection pool, which may lead to exceptions in the client PHP program.*/
  11. $memc->addServer("your_ip", 11212);
  12. $memc->setSaslAuthData("user", "password");
  13. }
  14. else
  15. {
  16. echo "Now connections is:".count($memc->getServerList())."<br>";
  17. }
  18. $memc->set("key", "value");
  19. echo "Get from OCS: ".$memc->get("key");
  20. //$memc->quit();/*Do not add ‘quit’ at the end of the code, otherwise persistent connections is changed to short connections. */
  21. ?>

Annotations are provided at the three points worth special attention in the preceding code. The keyword of ocs in the constructor is equivalent to a connection pool. Call new Memcached (ocs) and you can obtain the connection from the pool for use.

Execution results

Place the preceding code under the Apache working path /var/www/html/, and name it test.php. Enter in the browser: Http://your_ip:80/test.php.All the output results of the first eight attempts in the browser are:

  1. New connection
  2. Get from OCS: value

That is, all these eight attempts create new connections, while the subsequent attempts reuse these eight connections. The packet capture results also show that after the first eight attempts, connections are persistent, without socket reconnection or authentication.

After checking the httpd.conf file, it is clear that Apache started eight subprocesses and that is the reason for eight connections.

  1. #StartServers: numbers of server processes to start
  2. StartServers 8

As a result, eight connections are initialized in the connection pool with the ocs persistent_id and later requests can use the eight connections.

Page navigation

Copy a php file, and establish the persistent_id of the constructor. We still use ocs. The result is that the connection is switched (because the called Apache sub processes are different), but with no authentication or socket reconnection. That is, the PHP memcached persistent connection settings are effective. Usually we use the PHP-FPM mode. The FPM process keeps a persistent connection with the memcached server. As a result, the lifecycle of this connection is the same with that of the Apache process.

Thank you! We've received your feedback.