Migrar Memcache a Memorystore

Las aplicaciones web de Python escalables y de alto rendimiento suelen usar una caché de datos distribuida en memoria en lugar de un almacenamiento persistente sólido para algunas tareas.

La solución de App Engine para este problema es Memcache, un almacén de datos distribuido en memoria que se usa como caché para tareas específicas.

Al migrar de los servicios antiguos agrupados, la alternativa recomendada para Memcache de App Engine es Memorystore, un servicio de almacenamiento en caché basado en la nube totalmente gestionado que admite los motores de almacenamiento en caché de código abierto Redis y Memcached. En esta guía se explica cómo usar Memorystore para Redis, que permite crear cachés de aplicaciones que franquean el acceso a los datos en un tiempo inferior a un milisegundo.

Si tu aplicación Python usa Memcache solo para reducir la latencia de las solicitudes de ndb o de Cloud NDB, puedes usar la compatibilidad integrada de Cloud NDB con Redis en lugar de Memcache o Memorystore para Redis.

Antes de empezar, asegúrate de que tu aplicación no supere las cuotas de Memorystore para Redis.

Cuándo usar una caché de memoria para aplicaciones Python

En tus aplicaciones Python, los datos de sesión, las preferencias de los usuarios y otros datos devueltos por las consultas de páginas web son buenos candidatos para el almacenamiento en caché. Por lo general, si una consulta que se ejecuta con frecuencia devuelve un conjunto de resultados que no tienen que aparecer en tu aplicación de inmediato, puedes almacenar en caché los resultados. Las solicitudes posteriores pueden consultar la caché y solo consultar la base de datos si los resultados no están o han caducado.

Si almacenas un valor solo en Memorystore sin crear una copia de seguridad en el almacenamiento persistente, asegúrate de que tu aplicación se comporte de forma aceptable si el valor caduca y se elimina de la caché. Por ejemplo, si la ausencia repentina de los datos de sesión de un usuario provocara que la sesión no funcionara correctamente, esos datos probablemente deberían almacenarse en la base de datos, además de en Memorystore.

Antes de empezar

Si aún no lo has hecho, configura tu entorno de desarrollo de Python para usar una versión de Python compatible con Google Cloude instala herramientas de prueba para crear entornos de Python aislados.

Información sobre los permisos de Memorystore

Cada interacción con un servicio de Google Cloud debe autorizarse. Por ejemplo, para interactuar con una base de datos Redis alojada en Memorystore, tu aplicación debe proporcionar las credenciales de una cuenta que tenga autorización para acceder a Memorystore.

De forma predeterminada, tu aplicación proporciona las credenciales de la cuenta de servicio predeterminada de App Engine, que tiene autorización para acceder a las bases de datos del mismo proyecto que tu aplicación.

Si se cumple alguna de las siguientes condiciones, debes usar una técnica de autenticación alternativa que proporcione credenciales de forma explícita:

  • Tu aplicación y la base de datos de Memorystore están en proyectos diferentes.Google Cloud

  • Has cambiado los roles asignados a la cuenta de servicio predeterminada de App Engine.

Para obtener información sobre técnicas de autenticación alternativas, consulta el artículo Configurar la autenticación para aplicaciones de producción de servidor a servidor.

Visión general del proceso de migración

Para usar Memorystore en lugar de Memcache en tu aplicación Python, sigue estos pasos:

  1. Configura Memorystore para Redis. Para ello, debes crear una instancia de Redis en Memorystore y crear un acceso a VPC sin servidor que tu aplicación utilice para comunicarse con la instancia de Redis. El orden de creación de estas dos entidades independientes no es estricto y se pueden configurar en cualquier orden. Las instrucciones de esta guía muestran cómo configurar primero el acceso a VPC sin servidor.

  2. Instala una biblioteca de cliente para Redis y usa comandos de Redis para almacenar datos en caché.

    Memorystore para Redis es compatible con cualquier biblioteca de cliente de Redis.

    En esta guía se describe cómo usar la biblioteca de cliente redis-py para enviar comandos de Redis desde tu aplicación.

  3. Prueba las actualizaciones.

  4. Despliega tu aplicación en App Engine.

Configurar Memorystore para Redis

Para configurar Memorystore para Redis, sigue estos pasos:

  1. Conecta tu aplicación de App Engine a una red de VPC. Tu aplicación solo puede comunicarse con Memorystore a través de un conector VPC.

    Asegúrate de añadir la información de conexión de la VPC al archivo app.yaml tal como se describe en el artículo Configurar la aplicación para que use el conector.

  2. Anota la dirección IP y el número de puerto de la instancia de Redis que crees. Usará esta información cuando cree un cliente de Redis en su código.

  3. Crea una instancia de Redis en Memorystore.

    Cuando se te pida que selecciones una región para tu instancia de Redis, elige la misma región en la que se encuentra tu aplicación de App Engine.

Instalar dependencias

Para usar la biblioteca de cliente redis-py, sigue estos pasos:

  1. Actualiza el archivo app.yaml. Sigue las instrucciones correspondientes a tu versión de Python:

    Python 2

    En el caso de las aplicaciones de Python 2, añade las versiones más recientes de las bibliotecas grpcio y setuptools.

    A continuación, se muestra un ejemplo de archivo app.yaml:

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

    Python 3

    En el caso de las aplicaciones de Python 3, especifica el elemento runtime en el archivo app.yaml con una versión compatible de Python 3. Por ejemplo:

    runtime: python310 # or another support version
    

    El tiempo de ejecución de Python 3 instala las bibliotecas automáticamente, por lo que no es necesario especificar las bibliotecas integradas del tiempo de ejecución de Python 2 anterior. Si tu aplicación Python 3 usa otros servicios antiguos incluidos al migrar, puedes seguir especificando las bibliotecas integradas necesarias. De lo contrario, puedes eliminar las líneas innecesarias del archivo app.yaml.

  2. Actualiza el archivo requirements.txt. Sigue las instrucciones correspondientes a tu versión de Python:

    Python 2

    Añade las bibliotecas de cliente de Cloud para Memorystore for Redis a tu lista de dependencias en el archivo requirements.txt.

    redis
    

    Ejecuta pip install -t lib -r requirements.txt para actualizar la lista de bibliotecas disponibles para tu aplicación.

    Python 3

    Añade las bibliotecas de cliente de Cloud para Memorystore for Redis a tu lista de dependencias en el archivo requirements.txt.

    redis
    

    App Engine instala automáticamente estas dependencias durante la implementación de la aplicación en el tiempo de ejecución de Python 3, así que elimina la carpeta lib si existe.

  3. En el caso de las aplicaciones de Python 2, si tu aplicación usa bibliotecas integradas o copiadas especificadas en el directorio lib, debes especificar esas rutas en el archivo appengine_config.py, que se encuentra en la misma carpeta que el archivo 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)
    

Crear un cliente de Redis

Para interactuar con una base de datos Redis, tu código debe crear un cliente Redis para gestionar la conexión con tu base de datos Redis. En las siguientes secciones se describe cómo crear un cliente de Redis con la biblioteca de cliente redis-py.

Especificar variables de entorno

La biblioteca de cliente redis-py usa dos variables de entorno para crear la URL de tu base de datos Redis:

  • Variable para identificar la dirección IP de la base de datos Redis que has creado en Memorystore.
  • Variable para identificar el número de puerto de la base de datos Redis que has creado en Memorystore.

Te recomendamos que definas estas variables en el archivo app.yaml de tu aplicación en lugar de hacerlo directamente en el código. De esta forma, te resultará más fácil ejecutar tu aplicación en diferentes entornos, como un entorno local y App Engine.

Por ejemplo, añade las siguientes líneas a tu archivo app.yaml:

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

Importar redis-py y crear el cliente

Después de definir las variables de entorno REDISHOST y REDISPORT, usa las siguientes líneas para importar la biblioteca redis-py y crear un cliente:

  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 has usado una versión anterior de redis-py para otras aplicaciones, es posible que hayas usado la clase StrictClient en lugar de Client. Sin embargo, ahora redis-py recomienda Client en lugar de StrictClient.

Usar comandos de Redis para almacenar y recuperar datos en la caché

Aunque la base de datos Redis de Memorystore admite la mayoría de los comandos de Redis, solo tienes que usar unos pocos para almacenar y recuperar datos de la caché. En la siguiente tabla se sugieren comandos de Redis que puedes usar para almacenar datos en caché. Para saber cómo llamar a estos comandos desde tu aplicación, consulta la documentación de tu biblioteca de cliente.

Ten en cuenta que, en el caso de las aplicaciones de Python 2, aunque Memcache proporciona alternativas asíncronas para muchos de sus comandos, la biblioteca de cliente redis-py no siempre ofrece métodos asíncronos equivalentes. Si quieres que todas las interacciones con la caché sean asíncronas, puedes usar otras bibliotecas de cliente de Redis para Python.

Tarea Comando de Redis
Crea una entrada en la caché de datos y
define un tiempo de vencimiento para la entrada.
SETNX
MSETNX
Recuperar datos de la caché GET
MGET
Reemplazar los valores de caché actuales SET
MSET
Incrementar o reducir valores numéricos de la caché INCR
INCRBY
DECR
DECRBY
Eliminar entradas de la caché DEL
UNLINK
Admite interacciones simultáneas con la caché (comparar y definir) Consulta los detalles sobre las transacciones de Redis. Ten en cuenta que la biblioteca de cliente `redis-py` requiere que todas las transacciones se produzcan en una pipeline.

Probar las actualizaciones

Cuando pruebes tu aplicación de forma local, te recomendamos que ejecutes una instancia local de Redis para evitar interactuar con datos de producción (Memorystore no proporciona un emulador). Para instalar y ejecutar Redis de forma local, sigue las instrucciones de la documentación de Redis. Ten en cuenta que, por el momento, no es posible ejecutar Redis de forma local en Windows.

Para obtener más información sobre cómo probar aplicaciones Python, consulta Usar el servidor de desarrollo local.

Desplegar una aplicación

Una vez que tu aplicación se ejecute en el servidor de desarrollo local sin errores, haz lo siguiente:

  1. Prueba la aplicación en App Engine.

  2. Si la aplicación se ejecuta sin errores, usa la división del tráfico para aumentar lentamente el tráfico de la aplicación actualizada. Monitoriza la aplicación de cerca para detectar cualquier problema con la base de datos antes de dirigir más tráfico a la aplicación actualizada.

Siguientes pasos