Migra Memcache a Memorystore

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

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

Cuando se migran servicios en paquetes heredados, el reemplazo recomendado para Memcache de App Engine es Memorystore, un servicio de almacenamiento en caché basado en la nube completamente administrado que admite 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 puede crear almacenamientos en caché de aplicaciones para proporcionar acceso a datos en menos de un milisegundo.

Si tu app de Python usa Memcache a fin de reducir solo la latencia para las solicitudes ndb o Cloud NDB, puedes usar la compatibilidad integrada de Cloud NDB para Redis, en lugar de Memcache o Memorystore para Redis.

Antes de comenzar, asegúrate de que la app permanezca dentro de las cuotas de Memorystore para Redis.

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

En tus apps de Python, los datos de sesión, las preferencias de usuario y otros datos que muestran las consultas para páginas web son buenos candidatos a la hora de almacenar en caché. Por lo general, si una consulta que se ejecuta con frecuencia muestra un conjunto de resultados que no necesitan aparecer en la app de inmediato, puedes almacenarlos en caché. En las solicitudes subsiguientes, se puede verificar la caché y consultar la base de datos solo si los resultados están ausentes o ya vencieron.

Si almacenas un valor solo en Memorystore sin crear una copia de seguridad en el almacenamiento persistente, asegúrate de que la aplicación se comporte de manera aceptable si el valor vence y se quita de la caché. Por ejemplo, si la ausencia repentina de los datos de sesión de un usuario provoca una falla de la sesión, esos datos deberían almacenarse en la base de datos además de en Memorystore.

Antes de comenzar

Si aún no lo has hecho, configura tu entorno de desarrollo de Python para usar una versión de Python que sea compatible con Google Cloud y, luego, instala herramientas de prueba para crear entornos de Python aislado.

Información sobre los permisos de Memorystore

Cada interacción con un servicio de Google Cloud debe estar autorizada. Por ejemplo, a fin de interactuar con una base de datos de Redis que se aloja en Memorystore, la app debe proporcionar las credenciales de una cuenta autorizada para acceder a Memorystore.

De forma predeterminada, la app proporciona las credenciales de la cuenta de servicio predeterminada de App Engine, que está autorizada para acceder a las bases de datos en el mismo proyecto que la app.

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

  • La app y la base de datos de Memorystore están en diferentes proyectos de Google Cloud.

  • Cambiaste las funciones asignadas a la cuenta de servicio predeterminada de App Engine.

Si deseas obtener información sobre técnicas de autenticación alternativas, consulta Configura la autenticación para aplicaciones de producción de servidor a servidor.

Descripción general del proceso de migración

Para usar Memorystore en lugar de Memcache en tu app de Python, haz lo siguiente:

  1. Configura Memorystore para Redis, que requiere que crees una instancia de Redis en Memorystore y un Acceso a VPC sin servidores que la app usará a fin de comunicarse con la instancia de Redis. El orden de creación de estas dos entidades independientes no es estricto y se puede configurar en cualquier orden. En las instrucciones de esta guía, primero se muestra cómo configurar el Acceso a VPC sin servidores.

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

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

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

  3. Prueba las actualizaciones.

  4. Implementa la app en App Engine.

Configura Memorystore para Redis

Si deseas configurar Memorystore para Redis, debes hacer lo siguiente:

  1. Conecta App Engine a una red de VPC. La app solo puede comunicarse con Memorystore a través de un conector de VPC.

    Asegúrate de agregar la información de conexión de VPC al archivo app.yaml como se describe en Configura la app para usar un conector.

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

  3. Crea una instancia de Redis en Memorystore.

    Cuando se te solicite seleccionar una región para la instancia de Redis, selecciona la misma región en la que se encuentra la app de App Engine.

Instala dependencias

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

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

    Python 2

    Para las apps de Python 2, agrega las versiones más recientes de las bibliotecas grpcio y setuptools.

    El siguiente es un archivo app.yaml de ejemplo:

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

    Python 3

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

    runtime: python310 # or another support version
    

    El entorno de ejecución de Python 3 instala bibliotecas de forma automática, por lo que no es necesario especificar bibliotecas integradas del entorno de ejecución de Python 2 anterior. Si tu app de Python 3 usa otros servicios agrupados en paquetes heredados durante la migración, puedes seguir especificando las bibliotecas integradas necesarias. De lo contrario, puedes borrar las líneas innecesarias en tu archivo app.yaml.

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

    Python 2

    Agrega las bibliotecas cliente de Cloud para Memorystore para Redis a tu lista de dependencias en el archivo requirements.txt.

    redis
    

    Ejecuta pip install -t lib -r requirements.txt a fin de actualizar la lista de bibliotecas disponibles para la app.

    Python 3

    Agrega las bibliotecas cliente de Cloud para Memorystore para Redis a tu lista de dependencias en el archivo requirements.txt.

    redis
    

    App Engine instala de forma automática estas dependencias durante la implementación de la app en el entorno de ejecución de Python 3, así que borra la carpeta lib, si existe una.

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

Crea un cliente de Redis

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

Especifica las variables de entorno

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

  • Una variable para identificar la dirección IP de la base de datos de Redis que creaste en Memorystore
  • Una variable para identificar el número de puerto de la base de datos de Redis que creaste en Memorystore

Te recomendamos definir estas variables en el archivo app.yaml de la app en lugar de definirlas directamente en el código. Esto facilita la ejecución de la app en diferentes entornos, como un entorno local y App Engine.

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

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

Importa redis-py y crea 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 usaste una versión anterior de redis-py para otras apps, tal vez usaste la clase StrictClient en lugar de Client. Sin embargo, ahora redis-py recomienda Client en lugar de StrictClient.

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

Si bien la base de datos de Redis para Memorystore admite la mayoría de los comandos de Redis, solo debes usar algunos comandos a fin de almacenar y recuperar datos de la caché. En la siguiente tabla, se sugieren los comandos de Redis que puedes usar para almacenar datos en caché. Para saber cómo llamar a estos comandos desde la app, consulta la documentación de la biblioteca cliente.

Ten en cuenta que, para las aplicaciones de Python 2, si bien Memcache proporciona alternativas asíncronas para muchos de sus comandos, la biblioteca cliente redis-py no siempre proporciona métodos asíncronos equivalentes. Si necesitas que todas las interacciones con la caché sean asíncronas, hay otras bibliotecas cliente de Redis para Python disponibles.

Tarea Comando de Redis
Crear una entrada en la caché de datos y
establecer una fecha de vencimiento para la entrada
SETNX
MSETNX
Recuperar los datos de la caché GET
MGET
Reemplazar los valores existentes de la caché SET
MSET
Aumentar o disminuir los valores numéricos de la caché INCR
INCRBY
DECR
DECRBY
Borrar las entradas de la caché DEL
UNLINK
Admitir interacciones simultáneas con la caché (comparar y establecer) Consulta los detalles sobre las transacciones de Redis. Ten en cuenta que la biblioteca cliente de redis-py requiere que todas las transacciones se realicen en una canalización.

Prueba las actualizaciones

Cuando pruebes la app de forma local, considera ejecutar una instancia local de Redis para evitar la interacción con los datos de producción (Memorystore no proporciona un emulador). Para instalar y ejecutar Redis de forma local, sigue las instrucciones en la documentación de Redis. Ten en cuenta que en este momento no es posible ejecutar Redis de manera local en Windows.

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

Implementa tu aplicación

Una vez que la app se ejecute en el servidor de desarrollo local sin errores, haz lo siguiente:

  1. Prueba la app en App Engine.

  2. Si la app se ejecuta sin errores, usa la división de tráfico para aumentar el tráfico de la app actualizada. Supervísala de cerca a fin de detectar cualquier problema en la base de datos antes de enrutar más tráfico a la app actualizada.

¿Qué sigue?