Migrer Memcache vers Memorystore

Pour certaines tâches, les applications Web Python évolutives à hautes performances utilisent souvent un cache de données en mémoire distribué plutôt qu'un stockage persistant robuste.

La solution App Engine pour cela est Memcache, un datastore distribué en mémoire utilisé comme cache pour des tâches spécifiques.

Lors de la migration d'anciens services groupés, le remplacement recommandé pour App Engine Memcache est Memorystore, un service de mise en cache cloud entièrement géré compatible avec les moteurs de mise en cache Open Source, Redis et Memcached. Ce guide explique comment créer des caches d'application offrant un accès aux données inférieur à une milliseconde à l'aide de Memorystore pour Redis.

Si votre application Python utilise Memcache pour ne réduire que la latence des requêtes ndb ou Cloud NDB, vous pouvez utiliser la compatibilité intégrée de Cloud NDB pour Redis au lieu de Memcache ou Memorystore pour Redis.

Avant de commencer, assurez-vous que votre application reste dans les quotas attribués à Memorystore pour Redis.

Quand utiliser un cache mémoire pour les applications Python ?

Dans vos applications Python, les données de session, les préférences utilisateur et les autres données renvoyées par les requêtes pour les pages Web sont de bons candidats pour la mise en cache. En général, si une requête fréquemment exécutée renvoie un ensemble de résultats qui n'ont pas besoin d'apparaître immédiatement dans votre application, vous pouvez mettre en cache ces résultats. Les requêtes suivantes peuvent consulter le cache, et n'effectuer la requête de base de données que si les résultats ne s'y trouvent pas ou sont arrivés à expiration.

Si vous stockez une valeur uniquement dans Memorystore sans la sauvegarder dans un espace de stockage persistant, assurez-vous que votre application réagit convenablement si la valeur expire et qu'elle est supprimée du cache. Par exemple, si l'absence soudaine des données liées à une session d'utilisateur est susceptible de causer un dysfonctionnement de la session, il serait préférable de stocker ces données dans la base de données en plus de Memorystore.

Avant de commencer

Si ce n'est pas déjà fait, configurez votre environnement de développement Python pour utiliser une version de Python compatible avec Google Cloud et installez des outils de test pour créer des environnements Python isolés.

Comprendre les autorisations de Memorystore

Chaque interaction avec un service Google Cloud doit être autorisée. Par exemple, pour interagir avec une base de données Redis hébergée par Memorystore, votre application doit fournir les identifiants d'un compte autorisé à accéder à Memorystore.

Par défaut, votre application fournit les identifiants du compte de service App Engine par défaut, autorisé à accéder aux bases de données du même projet que votre application.

Si l'une des conditions suivantes est remplie, vous devez utiliser une autre technique d'authentification qui fournit explicitement des identifiants :

  • Votre application et la base de données Memorystore font partie de différents projets Google Cloud.

  • Vous avez modifié les rôles attribués au compte de service App Engine par défaut.

Pour plus d'informations sur les autres techniques d'authentification, consultez la page Configurer l'authentification pour des applications de production serveur à serveur.

Présentation du processus de migration

Pour utiliser Memorystore au lieu de Memcache dans votre application Python, procédez comme suit:

  1. Configurez Memorystore pour Redis. Pour cela, vous devez créer une instance Redis sur Memorystore et un accès au VPC sans serveur qui permettra à votre application de communiquer avec l'instance Redis. L'ordre de création de ces deux entités indépendantes n'est pas strict et peut être configuré dans n'importe quel ordre. Les instructions de ce guide présentent d'abord la configuration de l'accès au VPC sans serveur.

  2. Installez une bibliothèque cliente pour Redis et mettez en cache les données à l'aide des commandes Redis.

    Memorystore pour Redis est compatible avec toute bibliothèque cliente pour Redis.

    Ce guide explique comment envoyer des commandes Redis depuis votre application à l'aide de la bibliothèque cliente redis-py.

  3. Testez vos mises à jour.

  4. Déployez l'application sur App Engine.

Configurer Memorystore pour Redis

Pour configurer Memorystore pour Redis :

  1. Associez votre App Engine à un réseau VPC. Votre application ne peut communiquer avec Memorystore que via un connecteur VPC.

    Veillez à ajouter les informations de connexion VPC à votre fichier app.yaml comme décrit dans la section Configurer une application pour utiliser un connecteur.

  2. Prenez note de l'adresse IP et du numéro de port de l'instance Redis que vous créez. Vous utiliserez ces informations au moment de créer un client Redis dans votre code.

  3. Créez une instance Redis dans Memorystore.

    Lorsque vous êtes invité à choisir une région pour votre instance Redis, sélectionnez la région dans laquelle se trouve votre application App Engine.

Installer les dépendances

Pour utiliser la bibliothèque cliente redis-py, procédez comme suit :

  1. Mettez à jour le fichier app.yaml. Suivez les instructions correspondant à votre version de Python :

    Python 2

    Pour les applications Python 2, ajoutez les dernières versions des bibliothèques grpcio et setuptools.

    Voici un exemple de fichier app.yaml :

    runtime: python27
    threadsafe: yes
    api_version: 1
    
    libraries:
    - name: grpcio
      version: latest
    - name: setuptools
      version: latest
    

    Python 3

    Pour les applications Python 3, spécifiez l'élément runtime de votre fichier app.yaml avec une version compatible de Python 3. Par exemple :

    runtime: python310 # or another support version
    

    L'environnement d'exécution Python 3 installe automatiquement les bibliothèques. Vous n'avez donc pas besoin de spécifier des bibliothèques intégrées à partir de l'environnement d'exécution Python 2 précédent. Si votre application Python 3 utilise d'autres anciens services groupés lors de la migration, vous pouvez continuer à spécifier les bibliothèques intégrées nécessaires. Sinon, vous pouvez supprimer les lignes inutiles dans votre fichier app.yaml.

  2. Mettez à jour le fichier requirements.txt. Suivez les instructions correspondant à votre version de Python :

    Python 2

    Ajoutez les bibliothèques clientes Cloud pour Memorystore pour Redis à votre liste de dépendances dans le fichier requirements.txt.

    redis
    

    Exécutez pip install -t lib -r requirements.txt pour mettre à jour la liste des bibliothèques disponibles pour votre application.

    Python 3

    Ajoutez les bibliothèques clientes Cloud pour Memorystore pour Redis à votre liste de dépendances dans le fichier requirements.txt.

    redis
    

    App Engine installe automatiquement ces dépendances dans l'environnement d'exécution Python 3 lors du déploiement de l'application. Par conséquent, supprimez le dossier lib s'il existe.

  3. Pour les applications Python 2, si votre application utilise des bibliothèques intégrées ou copiées spécifiées dans le répertoire lib, vous devez spécifier ces chemins d'accès dans le fichier appengine_config.py, situé dans le même dossier que votre fichier app.yaml :

    import pkg_resources
    from google.appengine.ext import vendor
    
    # Set PATH to your libraries folder.
    PATH = 'lib'
    # Add libraries installed in the PATH folder.
    vendor.add(PATH)
    # Add libraries to pkg_resources working set to find the distribution.
    pkg_resources.working_set.add_entry(PATH)
    

Créer un client Redis

Pour interagir avec une base de données Redis, votre code doit créer un client Redis qui gèrera la connexion à votre base de données Redis. Les sections suivantes décrivent la création d'un client Redis à l'aide de la bibliothèque cliente redis-py.

Spécifier des variables d'environnement

La bibliothèque cliente redis-py utilise deux variables d'environnement pour assembler l'URL de votre base de données Redis :

  • Une variable permettant d'identifier l'adresse IP de la base de données Redis que vous avez créée dans Memorystore
  • Une variable permettant d'identifier le numéro de port de la base de données Redis que vous avez créée dans Memorystore

Nous vous recommandons de définir ces variables dans le fichier app.yaml de votre application au lieu de les définir directement dans votre code. Cela facilitera l'exécution de votre application dans différents environnements, tels qu'un environnement local et App Engine.

Par exemple, ajoutez les lignes suivantes à votre fichier app.yaml :

 env_variables:
      REDISHOST: '10.112.12.112'
      REDISPORT: '6379'

Importer redis-py et créer le client

Après avoir défini les variables d'environnement REDISHOST et REDISPORT, utilisez les lignes suivantes pour importer la bibliothèque redis-py et créer un client :

  import redis

  redis_host = os.environ.get('REDISHOST', 'localhost')
  redis_port = int(os.environ.get('REDISPORT', 6379))
  redis_client = redis.Redis(host=redis_host, port=redis_port)

Si vous avez utilisé une version plus ancienne de redis-py pour d'autres applications, il est possible que vous ayez utilisé la classe StrictClient au lieu de Client. Cependant, redis-py recommande désormais Client au lieu de StrictClient.

Utiliser les commandes Redis pour stocker et récupérer des données dans le cache

Bien que la base de données Redis Memorystore soit compatible avec la plupart des commandes Redis, vous n'avez besoin que de quelques commandes pour stocker et récupérer des données à partir du cache. Le tableau suivant suggère des commandes Redis que vous pouvez utiliser pour mettre en cache des données. Pour savoir comment appeler ces commandes depuis votre application, consultez la documentation de votre bibliothèque cliente.

Pour les applications Python 2, bien que Memcache propose des alternatives asynchrones pour la plupart de ses commandes, il est à noter que la bibliothèque cliente redis-py ne fournit pas toujours de méthodes asynchrones équivalentes. Si vous souhaitez que toutes les interactions avec le cache soient asynchrones, il existe d'autres bibliothèques clientes Redis pour Python.

Tâche Commande Redis
Créer une entrée dans le cache de données et
définir un délai d'expiration pour l'entrée
SETNX
MSETNX
Récupérer les données du cache GET
MGET
Remplacer les valeurs de cache existantes SET
MSET
Augmenter ou diminuer les valeurs du cache numérique INCR
INCRBY
DECR
DECRBY
Supprimer les entrées du cache DEL
UNLINK
Accepter les interactions simultanées avec le cache ("compare and set") Consultez les informations concernant les transactions avec Redis. Notez que la bibliothèque cliente redis-py exige que toutes les transactions aient lieu dans un pipeline.

Tester vos mises à jour

Lorsque vous testez votre application en local, songez à exécuter une instance locale de Redis pour éviter toute interaction avec les données de production (Memorystore ne fournit pas d'émulateur). Pour installer et exécuter Redis en local, suivez les instructions de la documentation Redis. Il est actuellement impossible d'exécuter Redis en local sous Windows.

Pour en savoir plus sur les tests des applications Python, consultez Utiliser le serveur de développement local.

Déployer l'application

Une fois que votre application est exécutée sur le serveur de développement local sans erreur :

  1. Testez l'application sur App Engine.

  2. Si l'application s'exécute sans erreur, répartissez le trafic pour augmenter lentement le trafic de votre application mise à jour. Surveillez attentivement les éventuels problèmes de base de données avant d'acheminer davantage de trafic vers l'application mise à jour.

Étapes suivantes