Description du problème
Certains utilisateurs de PHP signalent que leurs tests de performance sur ApsaraDB for Memcache n'atteignent pas les métriques attendues. Dans la plupart de ces cas, l'application accède à ApsaraDB for Memcache via le service web Apache et utilise des connexions éphémères. Chaque connexion éphémère engendre un coût supérieur à celui d'une simple réutilisation de socket, car elle implique également une procédure complexe de réauthentification. Ce surcoût est bien plus élevé que celui d'une requête ordinaire, ce qui réduit considérablement l'efficacité de votre site web.
Solution
Nous vous recommandons donc de remplacer les connexions éphémères par des connexions persistantes. Toutefois, ApsaraDB for Memcache nécessite l'extension PHP Memcached qui, contrairement à l'extension memcache, ne propose pas d'interface pconnect. Les étapes suivantes expliquent comment configurer une connexion persistante en PHP.
D'après la documentation PHP Memcached :
Description
Memcached::__construct ([ string $persistent_id ] ) Creates a Memcached instance representing the connection to the memcache servers.
Parameters
persistent_id By default the Memcached instances are destroyed at the end of the request. To create an instance that persists between requests, use persistent_id to specify a unique ID for the instance. All instances created with the same persistent_id will share the same connection.
Autrement dit, vous partagez une connexion en transmettant le même persistent_id au constructeur. Voici le code correspondant :
<?php
$memc = new Memcached('ocs');// The 'ocs' here is the persistent_id
if (count($memc->getServerList()) == 0) /* Check before you establish a connection */
{
echo "New connection"."<br>";
/* Keep every option inside the condition, because some options cause a reconnection and turn a persistent connection into a short-lived one. */
$memc->setOption(Memcached::OPT_COMPRESSION, false);
$memc->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
$memc->setOption(Memcached::OPT_TCP_NODELAY, true); //Important. PHP Memcached has a bug that adds a fixed 40 ms delay when the value you get does not exist. Enable this option to avoid the bug.
/* The addServer code must also stay inside the condition. Otherwise you build the 'ocs' connection pool again, which can cause exceptions in the PHP client program. */
$memc->addServer("your_ip", 11212);
$memc->setSaslAuthData("user", "password");
}
else
{
echo "Now connections is:".count($memc->getServerList())."<br>";
}
$memc->set("key", "value");
echo "Get from OCS: ".$memc->get("key");
//$memc->quit();/* Never add quit at the end of the code. Otherwise the connection becomes short-lived. */
?>
Les trois points auxquels vous devez prêter une attention particulière dans le code ci-dessus sont indiqués par des commentaires. Le mot-clé ocs dans le constructeur agit comme un pool de connexions : tout code nécessitant une connexion appelle new Memcached('ocs') et en récupère une depuis le pool.
Résultat
Placez le code précédent dans le répertoire de travail d'Apache /var/www/html/, nommez-le test.php, puis saisissez http://your_ip:80/test.php dans le navigateur. Pour les huit premières requêtes, le navigateur affiche la sortie suivante :
New connection
Get from OCS: value
Cela signifie que chacune de ces huit requêtes crée une nouvelle connexion, et que toutes les requêtes suivantes réutilisent l'une de ces huit connexions. Une capture de paquets confirme également que tout le trafic après la huitième requête transite par des connexions persistantes, sans reconnexion de socket ni authentification.
Pourquoi observe-t-on exactement huit connexions ? Le fichier de configuration httpd.conf indique qu'Apache démarre huit processus enfants :
#StartServers: numbers of server processes to start
StartServers 8
Le pool de connexions associé au persistent_id ocs initialise donc exactement huit connexions, et toutes les requêtes ultérieures utilisent ces mêmes connexions.
Ensuite, testez la navigation entre les pages. Copiez le fichier PHP et conservez ocs comme persistent_id du constructeur qui établit la connexion. La requête passe d'une connexion à une autre, car elle est traitée par un processus enfant Apache différent, mais aucune authentification ni reconnexion de socket ne se produit. Cela prouve que la configuration des connexions persistantes PHP Memcached fonctionne correctement. PHP-FPM est le mode que nous utilisons habituellement : le processus FPM maintient une connexion persistante vers le serveur Memcached, de sorte que le cycle de vie de cette connexion correspond à celui du processus Apache.