Aller au contenu

memc: Version étendue du module memcached standard de NGINX

Installation

Vous pouvez installer ce module dans n'importe quelle distribution basée sur RHEL, y compris, mais sans s'y limiter :

  • RedHat Enterprise Linux 7, 8, 9 et 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 et Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-memc
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-memc

Activez le module en ajoutant ce qui suit en haut de /etc/nginx/nginx.conf :

load_module modules/ngx_http_memc_module.so;

Ce document décrit nginx-module-memc v0.20 publié le 27 décembre 2023.


 # GET /foo?key=dog
 #
 # POST /foo?key=cat
 # Valeur du chat...
 #
 # PUT /foo?key=bird
 # Valeur de l'oiseau...
 #
 # DELETE /foo?key=Tiger
 location /foo {
     set $memc_key $arg_key;

     # $memc_cmd par défaut est get pour GET,
     #   add pour POST, set pour PUT, et
     #   delete pour la méthode de requête DELETE.

     memc_pass 127.0.0.1:11211;
 }
 # GET /bar?cmd=get&key=cat
 #
 # POST /bar?cmd=set&key=dog
 # Ma valeur pour la clé "dog"...
 #
 # DELETE /bar?cmd=delete&key=dog
 # GET /bar?cmd=delete&key=dog
 location /bar {
     set $memc_cmd $arg_cmd;
     set $memc_key $arg_key;
     set $memc_flags $arg_flags; # par défaut 0
     set $memc_exptime $arg_exptime; # par défaut 0

     memc_pass 127.0.0.1:11211;
 }
 # GET /bar?cmd=get&key=cat
 # GET /bar?cmd=set&key=dog&val=animal&flags=1234&exptime=2
 # GET /bar?cmd=delete&key=dog
 # GET /bar?cmd=flush_all
 location /bar {
     set $memc_cmd $arg_cmd;
     set $memc_key $arg_key;
     set $memc_value $arg_val;
     set $memc_flags $arg_flags; # par défaut 0
     set $memc_exptime $arg_exptime; # par défaut 0

     memc_cmds_allowed get set add delete flush_all;

     memc_pass 127.0.0.1:11211;
 }
   http {
     ...
     upstream backend {
        server 127.0.0.1:11984;
        server 127.0.0.1:11985;
     }
     server {
         location /stats {
             set $memc_cmd stats;
             memc_pass backend;
         }
         ...
     }
   }
   ...
 # lire les flags memcached dans l'en-tête Last-Modified
 # pour répondre 304 à un GET conditionnel
 location /memc {
     set $memc_key $arg_key;

     memc_pass 127.0.0.1:11984;

     memc_flags_to_last_modified on;
 }
 location /memc {
     set $memc_key foo;
     set $memc_cmd get;

     # accéder à la socket de domaine unix écoutée par memcached
     memc_pass unix:/tmp/memcached.sock;
 }

Description

Ce module étend le module memcached standard pour prendre en charge presque l'ensemble du protocole ascii memcached.

Il vous permet de définir une interface REST personnalisée pour vos serveurs memcached ou d'accéder à memcached de manière très efficace depuis le serveur nginx par le biais de sous-requêtes ou de requêtes fictives indépendantes.

Ce module n'est pas censé être intégré dans le noyau de Nginx car j'ai utilisé Ragel pour générer les parseurs de réponse memcached (en C) pour le plaisir :)

Si vous allez utiliser ce module pour mettre en cache les réponses de localisation par défaut, essayez srcache-nginx-module avec ce module pour y parvenir.

Lorsqu'il est utilisé en conjonction avec lua-nginx-module, il est recommandé d'utiliser la bibliothèque lua-resty-memcached au lieu de ce module, car cette dernière est beaucoup plus flexible et efficace en mémoire.

Connexions keep-alive aux serveurs memcached

Vous avez besoin de HttpUpstreamKeepaliveModule avec ce module pour des connexions TCP keep-alive à vos serveurs memcached en arrière-plan.

Voici un exemple de configuration :

   http {
     upstream backend {
       server 127.0.0.1:11211;

       # un pool avec au maximum 1024 connexions
       # et ne pas distinguer les serveurs :
       keepalive 1024;
     }

     server {
         ...
         location /memc {
             set $memc_cmd get;
             set $memc_key $arg_key;
             memc_pass backend;
         }
     }
   }

Comment ça fonctionne

Il implémente le protocole TCP memcached tout seul, basé sur le mécanisme upstream. Tout ce qui concerne l'I/O est non-bloquant.

Le module lui-même ne garde pas les connexions TCP avec les serveurs memcached en amont entre les requêtes, tout comme les autres modules en amont. Pour une solution fonctionnelle, voir la section Connexions keep-alive aux serveurs memcached.

Commandes Memcached prises en charge

Les commandes de stockage memcached set, add, replace, prepend, et append utilisent le $memc_key comme clé, $memc_exptime comme temps d'expiration (ou délai) (par défaut 0), $memc_flags comme flags (par défaut 0), pour construire les requêtes memcached correspondantes.

Si $memc_value n'est pas défini du tout, alors le corps de la requête sera utilisé comme valeur de $memc_value, sauf pour les commandes incr et decr. Notez que si $memc_value est défini comme une chaîne vide (""), cette chaîne vide sera tout de même utilisée comme valeur.

Les commandes memcached suivantes ont été implémentées et testées (avec leurs paramètres marqués par les variables nginx correspondantes définies par ce module) :

get $memc_key

Récupère la valeur en utilisant une clé.

   location /foo {
       set $memc_cmd 'get';
       set $memc_key 'my_key';

       memc_pass 127.0.0.1:11211;

       add_header X-Memc-Flags $memc_flags;
   }

Renvoie 200 OK avec la valeur mise dans le corps de la réponse si la clé est trouvée, ou 404 Not Found sinon. Le numéro flags sera défini dans la variable $memc_flags, il est donc souvent souhaitable de mettre cette information dans les en-têtes de réponse par le biais de la directive standard add_header.

Il renvoie 502 pour ERROR, CLIENT_ERROR, ou SERVER_ERROR.

set $memc_key $memc_flags $memc_exptime $memc_value

Pour utiliser le corps de la requête comme valeur memcached, il suffit d'éviter de définir la variable $memc_value :

   # POST /foo
   # ma valeur...
   location /foo {
       set $memc_cmd 'set';
       set $memc_key 'my_key';
       set $memc_flags 12345;
       set $memc_exptime 24;

       memc_pass 127.0.0.1:11211;
   }

Ou laissez la $memc_value contenir la valeur :

   location /foo {
       set $memc_cmd 'set';
       set $memc_key 'my_key';
       set $memc_flags 12345;
       set $memc_exptime 24;
       set $memc_value 'my_value';

       memc_pass 127.0.0.1:11211;
   }

Renvoie 201 Created si le serveur memcached en amont répond STORED, 200 pour NOT_STORED, 404 pour NOT_FOUND, 502 pour ERROR, CLIENT_ERROR, ou SERVER_ERROR.

Les réponses memcached originales sont renvoyées comme corps de réponse sauf pour 404 NOT FOUND.

add $memc_key $memc_flags $memc_exptime $memc_value

Semblable à la commande set.

replace $memc_key $memc_flags $memc_exptime $memc_value

Semblable à la commande set.

append $memc_key $memc_flags $memc_exptime $memc_value

Semblable à la commande set.

Notez qu'au moins la version 1.2.2 de memcached ne prend pas en charge les commandes "append" et "prepend". Au moins les versions 1.2.4 et ultérieures semblent prendre en charge ces deux commandes.

prepend $memc_key $memc_flags $memc_exptime $memc_value

Semblable à la commande append.

delete $memc_key

Supprime l'entrée memcached en utilisant une clé.

   location /foo {
       set $memc_cmd delete;
       set $memc_key my_key;

       memc_pass 127.0.0.1:11211;
   }

Renvoie 200 OK si supprimé avec succès, 404 Not Found pour NOT_FOUND, ou 502 pour ERROR, CLIENT_ERROR, ou SERVER_ERROR.

Les réponses memcached originales sont renvoyées comme corps de réponse sauf pour 404 NOT FOUND.

delete $memc_key $memc_exptime

Semblable à la commande delete $memc_key sauf qu'elle accepte un temps d'expiration optionnel spécifié par la variable $memc_exptime.

Cette commande n'est plus disponible dans la dernière version de memcached 1.4.4.

incr $memc_key $memc_value

Incrémente la valeur existante de $memc_key par le montant spécifié par $memc_value :

   location /foo {
       set $memc_cmd incr;
       set $memc_key my_key;
       set $memc_value 2;
       memc_pass 127.0.0.1:11211;
   }

Dans l'exemple précédent, chaque fois que nous accédons à /foo, la valeur de my_key sera incrémentée de 2.

Renvoie 200 OK avec la nouvelle valeur associée à cette clé comme corps de réponse si réussi, ou 404 Not Found si la clé n'est pas trouvée.

Il renvoie 502 pour ERROR, CLIENT_ERROR, ou SERVER_ERROR.

decr $memc_key $memc_value

Semblable à incr $memc_key $memc_value.

flush_all

Marque toutes les clés sur le serveur memcached comme expirées :

   location /foo {
       set $memc_cmd flush_all;
       memc_pass 127.0.0.1:11211;
   }

flush_all $memc_exptime

Tout comme flush_all mais accepte également un temps d'expiration spécifié par la variable $memc_exptime.

stats

Fait en sorte que le serveur memcached affiche des statistiques et des paramètres généraux.

   location /foo {
       set $memc_cmd stats;
       memc_pass 127.0.0.1:11211;
   }

Renvoie 200 OK si la requête réussit, ou 502 pour ERROR, CLIENT_ERROR, ou SERVER_ERROR.

La sortie brute de la commande stats du serveur memcached en amont sera mise dans le corps de la réponse.

Directives

Toutes les directives standard du module memcached dans nginx 0.8.28 sont directement héritées, avec les préfixes memcached_ remplacés par memc_. Par exemple, la directive memcached_pass s'écrit memc_pass.

Ici, nous ne documentons que les deux directives les plus importantes (la dernière étant une nouvelle directive introduite par ce module).

memc_pass

syntax: memc_pass <adresse IP du serveur memcached>:<port du serveur memcached>

syntax: memc_pass <nom d'hôte du serveur memcached>:<port du serveur memcached>

syntax: memc_pass <nom_backend_en_amont>

syntax: memc_pass unix:<chemin_vers_socket_de_domaine_unix>

default: aucun

context: http, server, location, if

phase: content

Spécifiez le backend du serveur memcached.

memc_cmds_allowed

syntax: memc_cmds_allowed <cmd>...

default: aucun

context: http, server, location, if

Liste des commandes memcached autorisées à accéder. Par défaut, toutes les commandes memcached prises en charge par ce module sont accessibles. Un exemple est

    location /foo {
        set $memc_cmd $arg_cmd;
        set $memc_key $arg_key;
        set $memc_value $arg_val;

        memc_pass 127.0.0.1:11211;

        memc_cmds_allowed get;
    }

memc_flags_to_last_modified

syntax: memc_flags_to_last_modified on|off

default: off

context: http, server, location, if

Lire les flags memcached en tant que secondes depuis l'époque et les définir comme valeur de l'en-tête Last-Modified. Pour un GET conditionnel, cela signalera à nginx de renvoyer une réponse 304 Not Modified pour économiser de la bande passante.

memc_connect_timeout

syntax: memc_connect_timeout <temps>

default: 60s

context: http, server, location

Le délai d'attente pour se connecter au serveur memcached, en secondes par défaut.

Il est judicieux de toujours spécifier explicitement l'unité de temps pour éviter toute confusion. Les unités de temps prises en charge sont "s" (secondes), "ms" (millisecondes), "y" (années), "M" (mois), "w" (semaines), "d" (jours), "h" (heures), et "m" (minutes).

Ce temps doit être inférieur à 597 heures.

memc_send_timeout

syntax: memc_send_timeout <temps>

default: 60s

context: http, server, location

Le délai d'attente pour envoyer des requêtes TCP au serveur memcached, en secondes par défaut.

Il est judicieux de toujours spécifier explicitement l'unité de temps pour éviter toute confusion. Les unités de temps prises en charge sont "s" (secondes), "ms" (millisecondes), "y" (années), "M" (mois), "w" (semaines), "d" (jours), "h" (heures), et "m" (minutes).

Ce temps doit être inférieur à 597 heures.

memc_read_timeout

syntax: memc_read_timeout <temps>

default: 60s

context: http, server, location

Le délai d'attente pour lire les réponses TCP du serveur memcached, en secondes par défaut.

Il est judicieux de toujours spécifier explicitement l'unité de temps pour éviter toute confusion. Les unités de temps prises en charge sont "s" (secondes), "ms" (millisecondes), "y" (années), "M" (mois), "w" (semaines), "d" (jours), "h" (heures), et "m" (minutes).

Ce temps doit être inférieur à 597 heures.

memc_buffer_size

syntax: memc_buffer_size <taille>

default: 4k/8k

context: http, server, location

Cette taille de tampon est utilisée pour le tampon mémoire pour contenir

  • la réponse complète pour les commandes memcached autres que get,
  • l'en-tête de réponse complet (c'est-à-dire, la première ligne de la réponse) pour la commande memcached get.

Cette taille par défaut est la taille de la page, pouvant être 4k ou 8k.

memc_ignore_client_abort

syntax: memc_ignore_client_abort on|off

default: off

context: location

Détermine si la connexion avec un serveur memcache doit être fermée lorsque un client ferme une connexion sans attendre de réponse.

Cette directive a été ajoutée pour la première fois dans la version v0.14.

Changements

Les changements de chaque version de ce module peuvent être obtenus à partir des journaux de modifications du bundle OpenResty :

http://openresty.org/#Changes

Test Suite

Ce module est livré avec une suite de tests pilotée par Perl. Les cas de test sont également déclaratifs. Merci au module Test::Base dans le monde Perl.

Pour l'exécuter de votre côté :

 $ PATH=/path/to/your/nginx-with-memc-module:$PATH prove -r t

Vous devez terminer tous les processus Nginx avant d'exécuter la suite de tests si vous avez modifié le binaire du serveur Nginx.

Soit LWP::UserAgent ou IO::Socket est utilisé par le scaffold de test.

Comme un seul serveur nginx (par défaut, localhost:1984) est utilisé dans tous les scripts de test (.t fichiers), il est inutile d'exécuter la suite de tests en parallèle en spécifiant -jN lors de l'invocation de l'utilitaire prove.

Vous devez également garder un serveur memcached écoutant sur le port 11211 à localhost avant d'exécuter la suite de tests.

Certaines parties de la suite de tests nécessitent également que les modules rewrite et echo soient activés lors de la construction de Nginx.

Voir aussi

GitHub

Vous pouvez trouver des conseils de configuration supplémentaires et de la documentation pour ce module dans le dépôt GitHub pour nginx-module-memc.