1. Descripción general
La serie de codelabs Serverless Migration Station (instructivos prácticos y autoaprendizaje) y los videos relacionados tienen como objetivo ayudar a los desarrolladores de Google Cloud sin servidores a modernizar sus apps guiándolos a través de una o más migraciones, en especial al alejarse de los servicios heredados. De esta manera, tus apps serán más portátiles, y tendrás más opciones y flexibilidad, lo que te permitirá integrarlas con una variedad más amplia de productos de Cloud y acceder a ella, y actualizar con mayor facilidad a versiones de idiomas más recientes. Aunque inicialmente se enfoca en los primeros usuarios de Cloud, principalmente los desarrolladores de App Engine (entorno estándar), esta serie es lo suficientemente amplia como para incluir otras plataformas sin servidores como Cloud Functions y Cloud Run, o cualquier otra, si corresponde.
El propósito de este codelab es mostrarles a los desarrolladores de App Engine de Python 2 cómo migrar de Memcache de App Engine a Cloud Memorystore (para Redis). También hay una migración implícita de ndb
de App Engine a Cloud NDB, pero se trata principalmente en el codelab del módulo 2. echa un vistazo para obtener más información paso a paso.
En un próximo lab,
- Configura una instancia de Cloud Memorystore (desde la consola de Cloud o la herramienta de
gcloud
) - Configura un conector de Acceso a VPC sin servidores de Cloud (desde Cloud Console o la herramienta de
gcloud
) - Migra de App Engine Memcache a Cloud Memorystore
- Implementar el almacenamiento en caché con Cloud Memorystore en una app de muestra
- Migra de App Engine
ndb
a Cloud NDB
Requisitos
- Un proyecto de Google Cloud con una cuenta de facturación activa (este no es un codelab gratuito)
- Habilidades básicas de Python
- Conocimiento práctico de los comandos comunes de Linux
- Conocimientos básicos sobre el desarrollo y la implementación de aplicaciones de App Engine
- Una aplicación de App Engine del módulo 12 que funcione (completa el codelab del módulo 12 [recomendado] o copia la app del módulo 12 del repositorio)
Encuesta
¿Cómo usarás este instructivo?
¿Cómo calificarías tu experiencia en Python?
¿Cómo calificarías tu experiencia en el uso de los servicios de Google Cloud?
2. Información general
En este codelab, se muestra cómo migrar una app de ejemplo de Memcache de App Engine (y NDB) a Cloud Memorystore (y Cloud NDB). Este proceso implica reemplazar las dependencias de los paquetes de servicios de App Engine, lo que hace que tus apps sean más portátiles. Puedes optar por permanecer en App Engine o considerar cambiar a cualquiera de las alternativas descritas anteriormente.
Esta migración requiere más esfuerzo que las demás de esta serie. El reemplazo recomendado de Memcache de App Engine es Cloud Memorystore, un servicio de almacenamiento en caché completamente administrado y basado en la nube. Memorystore admite dos motores populares de almacenamiento en caché de código abierto, Redis y Memcached. En este módulo de migración, se usa Cloud Memorystore para Redis. Puedes obtener más información en la Descripción general de Memorystore y Redis.
Debido a que Memorystore requiere un servidor en ejecución, también se necesita Cloud VPC. Específicamente, debe crearse un conector de Acceso a VPC sin servidores para que la app de App Engine pueda conectarse a la instancia de Memorystore a través de su dirección IP privada. Cuando hayas completado este ejercicio, habrás actualizado la app para que, si bien se comporte como antes, Cloud Memorystore sea el servicio de almacenamiento en caché y reemplace el servicio Memcache de App Engine.
Este instructivo comienza con la app de ejemplo del módulo 12 en Python 2 seguida de una actualización menor adicional, opcional y menor a Python 3. Si ya sabes acceder a los servicios empaquetados de App Engine desde Python 3 mediante el SDK de App Engine para Python 3, puedes comenzar con la versión de Python 3 de la app de ejemplo del Módulo 12. En ese caso, se quitará el uso del SDK, ya que Memorystore no es un servicio empaquetado de App Engine. Aprender a usar el SDK de Python 3 para App Engine está fuera del alcance de este instructivo.
En este instructivo, se presentan los siguientes pasos clave:
- Configuración y trabajo previo
- Configura servicios de almacenamiento en caché
- Actualiza archivos de configuración
- Actualizar la aplicación principal
3. Configuración y trabajo previo
Prepara un proyecto de Cloud
Te recomendamos que vuelvas a usar el mismo proyecto que usaste para completar el codelab del módulo 12. Como alternativa, puedes crear un proyecto completamente nuevo o reutilizar otro proyecto existente. Cada codelab de esta serie tiene un "COMENZAR" (el código de referencia desde el que comenzar) y "FINALIZAR" (la app migrada). Te proporcionamos el código FINISH para que puedas comparar tus soluciones con las nuestras en caso de que tengas problemas. Siempre puedes revertir a START si algo sale mal. Estos puntos de control están diseñados para garantizar que puedas aprender a realizar las migraciones con éxito.
Sin importar el proyecto de Cloud que uses, asegúrate de tener una cuenta de facturación activa. Además, asegúrate de que App Engine esté habilitado. Revisa y asegúrate de comprender las implicaciones de los costos generales relacionadas con estos instructivos. Sin embargo, a diferencia de otros de esta serie, en este codelab se usan recursos de Cloud que no tienen un nivel gratuito, por lo que se generarán algunos costos para completar el ejercicio. Se proporcionará información más específica sobre los costos junto con recomendaciones para reducir el uso, incluidas instrucciones al final sobre la liberación de recursos para minimizar los cargos de facturación.
Obtén app de ejemplo del modelo de referencia
A partir del código de referencia del módulo 12 desde el que comenzamos, este codelab te guiará paso a paso a través de la migración. Cuando termines, llegarás a una app del módulo 13 que funcione y se parecerá mucho al código de una de las carpetas FINISH. Estos son esos recursos:
- INICIO: App del módulo 12 con Python 2 (
mod12
) o Python 3 (mod12b
) - FINALIZAR: App del módulo 13 de Python 2 (
mod13a
) o Python 3 (mod13b
) - Repositorio de migración completo (clona o descarga ZIP)
La carpeta START debe contener los siguientes archivos:
$ ls README.md app.yaml main.py requirements.txt templates
Si comienzas desde la versión de Python 2, también habrá un archivo appengine_config.py
y, posiblemente, una carpeta lib
si completaste el codelab del módulo 12.
(Re)Implementa la app del Módulo 12
Pasos previos restantes:
- Vuelve a familiarizarte con la herramienta de línea de comandos de
gcloud
(si es necesario) - (Vuelve a implementar el código del módulo 12 en App Engine (si es necesario)
Los usuarios de Python 2 deben borrar y reinstalar la carpeta lib
con estos comandos:
rm -rf ./lib; pip install -t lib -r requirements.txt
Ahora todos (usuarios de Python 2 y 3) deberían subir el código a App Engine con este comando:
gcloud app deploy
Una vez implementada correctamente, confirma que la app se vea y funcione como la app en el módulo 12, una app web que hace un seguimiento de las visitas y las almacena en caché para el mismo usuario durante una hora:
Debido a que las visitas más recientes se almacenan en caché, las actualizaciones de la página deberían cargarse con bastante rapidez.
4. Configura servicios de almacenamiento en caché
Cloud Memorystore no es un servicio sin servidores. Se requiere una instancia. en este caso, uno ejecuta Redis. A diferencia de Memcache, Memorystore es un producto independiente de Cloud y no tiene un nivel gratuito, así que asegúrate de consultar la información de precios de Memorystore para Redis antes de continuar. Para minimizar los costos de este ejercicio, recomendamos la menor cantidad de recursos para operar: un nivel de servicio Básico y una capacidad de 1 GB.
La instancia de Memorystore está en una red diferente a la de tu app de App Engine (instancias), por lo que se debe crear un conector de Acceso a VPC sin servidores para que App Engine pueda acceder a tus recursos de Memorystore. Para minimizar los costos de VPC, elige el tipo de instancia (f1-micro
) y la menor cantidad de instancias que desees solicitar (sugerimos un mínimo 2 y máximo 3). Consulta también la página de información de precios de VPC.
Repetimos estas recomendaciones para reducir los costos mientras te guíamos en la creación de cada recurso necesario. Además, cuando crees recursos de Memorystore y VPC en la consola de Cloud, verás la calculadora de precios de cada producto en la esquina superior derecha, lo que te proporcionará una estimación del costo mensual (consulta la siguiente ilustración). Esos valores se ajustan automáticamente si cambias tus opciones. A grandes rasgos, esto es lo que deberías esperar ver:
Ambos recursos son obligatorios y no importa cuál crees primero. Si creas primero la instancia de Memorystore, la app de App Engine no podrá acceder a ella sin el conector de VPC. Del mismo modo, si creas primero el conector de VPC, no habrá nada en esa red de VPC con la que tu aplicación de App Engine pueda comunicarse. En este instructivo, primero creas la instancia de Memorystore y, luego, sigue el conector de VPC.
Una vez que ambos recursos estén en línea, agregarás la información relevante a app.yaml
para que tu app pueda acceder a la caché. También puedes consultar las guías de Python 2 o Python 3 en la documentación oficial. También vale la pena consultar la guía de almacenamiento en caché de datos de la página de migración de Cloud NDB ( Python 2 o Python 3).
Crea una instancia de Cloud Memorystore
Debido a que Cloud Memorystore no tiene un nivel gratuito, recomendamos asignar la menor cantidad de recursos para completar el codelab. Puedes mantener los costos al mínimo con estos parámetros de configuración:
- Selecciona el nivel de servicio más bajo: Básico (predeterminado en la consola: “Estándar”;
gcloud
predeterminado: “Básico”). - Elige la cantidad mínima de almacenamiento: 1 GB (valor predeterminado de la consola: 16 GB; valor predeterminado de
gcloud
: 1 GB). - Por lo general, las versiones más recientes de cualquier software requieren la mayor cantidad de recursos, pero probablemente no se recomienda seleccionar la versión más antigua. La segunda versión más reciente es la versión de Redis 5.0 (configuración predeterminada de la consola: 6.x).
Con esos parámetros de configuración en mente, la siguiente sección te guiará en la creación de la instancia desde la consola de Cloud. Si prefieres hacerlo desde la línea de comandos, omite este paso.
Desde la consola de Cloud
Ve a la página de Cloud Memorystore en la consola de Cloud (es posible que se te soliciten datos de facturación). Si aún no habilitas Memorystore, se te solicitará que lo hagas:
Una vez que la hayas habilitado (y posiblemente junto con la facturación), llegarás al panel de Memorystore. Aquí puedes ver todas las instancias que se crearon en tu proyecto. El proyecto que se muestra a continuación no tiene ninguno, por eso ves "No hay filas para mostrar". Para crear una instancia de Memorystore, haz clic en Crear instancia en la parte superior:
En esta página, se incluye un formulario que debes completar con la configuración deseada para crear la instancia de Memorystore:
Para mantener los costos bajos para este instructivo y su app de ejemplo, sigue las recomendaciones que mencionamos anteriormente. Luego de realizar tus selecciones, haz clic en Crear. El proceso de creación tarda varios minutos. Cuando finalice, copia la dirección IP y el número de puerto de la instancia para agregarlos a app.yaml
.
Desde la línea de comandos
Aunque es visualmente informativo crear instancias de Memorystore desde la consola de Cloud, algunas prefieren la línea de comandos. Antes de continuar, asegúrate de que gcloud
esté instalado e inicializado.
Al igual que con la consola de Cloud, se debe habilitar Cloud Memorystore para Redis. Ejecuta el comando gcloud services enable redis.googleapis.com
y espera a que se complete, como en este ejemplo:
$ gcloud services enable redis.googleapis.com Operation "operations/acat.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.
Si ya se habilitó el servicio, ejecutar el comando (de nuevo) no tiene efectos secundarios (negativos). Con el servicio habilitado, crearemos una instancia de Memorystore. Ese comando se ve de la siguiente manera:
gcloud redis instances create NAME --redis-version VERSION \ --region REGION --project PROJECT_ID
Elige un nombre para tu instancia de Memorystore. en este lab se usa “demo-ms
” como el nombre, junto con un ID del proyecto de "my-project
". La región de esta app de ejemplo es us-central1
(igual que us-central
), pero puedes usar una más cercana si la latencia es un problema. Debes seleccionar la misma región que tu aplicación de App Engine. Puedes seleccionar la versión de Redis que prefieras, pero estamos usando la versión 5, como se recomendó anteriormente. Dada esa configuración, este es el comando que usarías (junto con el resultado asociado):
$ gcloud redis instances create demo-ms --region us-central1 \ --redis-version redis_5_0 --project my-project Create request issued for: [demo-ms] Waiting for operation [projects/my-project/locations/us-central1/operations/operation-xxxx] to complete...done. Created instance [demo-ms].
A diferencia de la configuración predeterminada de la consola de Cloud, la configuración predeterminada de gcloud
es mínima. El resultado es que para ese comando no se requerían el nivel de servicio ni la cantidad de almacenamiento. Crear una instancia de Memorystore tarda varios minutos. Cuando esté listo, ten en cuenta la dirección IP y el número de puerto de la instancia, ya que pronto se agregarán a app.yaml
.
Confirma que se creó la instancia
Desde la consola de Cloud o la línea de comandos
Ya sea que hayas creado tu instancia desde la consola de Cloud o desde la línea de comandos, puedes confirmar que está disponible y lista para usarse con este comando: gcloud redis instances list --region REGION
Este es el comando para verificar las instancias en la región us-central1
, junto con el resultado esperado que muestra la instancia que acabamos de crear:
$ gcloud redis instances list --region us-central1 INSTANCE_NAME VERSION REGION TIER SIZE_GB HOST PORT NETWORK RESERVED_IP STATUS CREATE_TIME demo-ms REDIS_5_0 us-central1 BASIC 1 10.aa.bb.cc 6379 default 10.aa.bb.dd/29 READY 2022-01-28T09:24:45
Cuando se te solicite la información de la instancia o para configurar tu app, asegúrate de usar HOST
y PORT
(no RESERVED_IP
). El panel de Cloud Memorystore en la consola de Cloud ahora debería mostrar esa instancia:
Desde la máquina virtual de Compute Engine
Si tienes una máquina virtual (VM) de Compute Engine, también puedes enviar comandos directos de la instancia de Memorystore desde una VM para confirmar que funciona. Ten en cuenta que el uso de una VM puede tener costos asociados, independientemente de los recursos que ya estés usando.
Crear conector de Acceso a VPC sin servidores
Al igual que con Cloud Memorystore, puedes crear el conector de Cloud VPC sin servidores en la consola de Cloud o en la línea de comandos. De manera similar, Cloud VPC no tiene un nivel gratuito, por lo que recomendamos asignar la menor cantidad de recursos para completar el codelab a fin de reducir al mínimo los costos. Esto se puede lograr con la siguiente configuración:
- Selecciona la cantidad máxima de instancias más baja: 3 (la consola y
gcloud
son las predeterminadas: 10). - Elige el tipo de máquina de menor costo:
f1-micro
(configuración predeterminada de la consola:e2-micro
, nogcloud
predeterminada)
En la siguiente sección, se explica cómo crear el conector desde la consola de Cloud con la configuración de VPC de Cloud anterior. Si prefieres hacerlo desde la línea de comandos, pasa a la siguiente sección.
Desde la consola de Cloud
Dirígete a Cloud Networking “Acceso a VPC sin servidores” en la consola de Cloud (es posible que se te soliciten los datos de facturación). Si aún no has habilitado la API, se te solicitará que lo hagas:
Una vez que habilites la API (y posiblemente junto con la facturación), llegarás al panel en el que se muestran todos los conectores de VPC creados. El proyecto que se usó en la siguiente captura de pantalla no tiene ninguno, por eso dice: "No hay filas para mostrar". En tu consola, haz clic en Crear conector en la parte superior:
Completa el formulario con la configuración deseada:
Elige la configuración apropiada para tus propias aplicaciones. Para este instructivo y su app de ejemplo con necesidades mínimas, tiene sentido minimizar los costos, así que sigue las recomendaciones que mencionamos anteriormente. Una vez que hayas realizado tus selecciones, haz clic en Crear. La solicitud de un conector de VPC tardará unos minutos en completarse.
Desde la línea de comandos
Antes de crear un conector de VPC, habilita la API de Acceso a VPC sin servidores. Deberías ver un resultado similar después de ejecutar el siguiente comando:
$ gcloud services enable vpcaccess.googleapis.com Operation "operations/acf.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.
Con la API habilitada, se crea un conector de VPC con un comando que se ve de la siguiente manera:
gcloud compute networks vpc-access connectors create CONNECTOR_NAME \ --range 10.8.0.0/28 --region REGION --project PROJECT_ID
Elige un nombre para tu conector y una dirección IP de inicio del bloque de CIDR /28
sin usar. En este instructivo, se hacen las siguientes suposiciones:
- Project ID (ID del proyecto):
my-project
- Nombre del conector de VPC:
demo-vpc
- Cantidad mínima de instancias: 2 (predeterminado) y máx. de instancias: 3
- Tipo de instancia:
f1-micro
- Región:
us-central1
- Bloque CIDR de IPv4:
10.8.0.0/28
(como se recomienda en la consola de Cloud)
Si ejecutas el comando con las suposiciones anteriores en mente, puedes obtener un resultado similar al que se muestra a continuación:
$ gcloud compute networks vpc-access connectors create demo-vpc \ --max-instances 3 --range 10.8.0.0/28 --machine-type f1-micro \ --region us-central1 --project my-project Create request issued for: [demo-vpc] Waiting for operation [projects/my-project/locations/us-central1/operations/xxx] to complete...done. Created connector [demo-vpc].
El comando anterior omite la especificación de valores predeterminados, como la cantidad mínima de instancias de 2 y una red llamada default
. La creación de un conector de VPC tarda varios minutos en completarse.
Confirma que se creó el conector
Una vez que se haya completado el proceso, ejecuta el siguiente comando gcloud
, suponiendo que es la región us-central1
, para confirmar que se creó y que está listo para usarse:
$ gcloud compute networks vpc-access connectors list --region us-central1 CONNECTOR_ID REGION NETWORK IP_CIDR_RANGE SUBNET SUBNET_PROJECT MIN_THROUGHPUT MAX_THROUGHPUT STATE demo-vpc us-central1 default 10.8.0.0/28 200 300 READY
De manera similar, el panel ahora debería mostrar el conector que acabas de crear:
Toma nota del ID del proyecto de Cloud, el nombre del conector de VPC y la región.
Ahora que creaste los recursos adicionales de Cloud necesarios, ya sea mediante la línea de comandos o en la consola, es momento de actualizar la configuración de la aplicación para admitir su uso.
5. Actualiza archivos de configuración
El primer paso es realizar todas las actualizaciones necesarias en los archivos de configuración. El objetivo principal de este codelab es ayudar a los usuarios de Python 2 a migrar. Sin embargo, el seguimiento del contenido suele incluir información sobre la portabilidad a Python 3 en cada sección que aparece a continuación.
requirements.txt
En esta sección, agregamos paquetes para admitir Cloud Memorystore y Cloud NDB. En el caso de Cloud Memorystore para Redis, es suficiente usar el cliente estándar de Redis para Python (redis
), ya que no hay una biblioteca cliente de Cloud Memorystore en sí. Agrega redis
y google-cloud-ndb
a requirements.txt
, uniéndote a flask
del módulo 12:
flask
redis
google-cloud-ndb
Este archivo requirements.txt
no presenta ningún número de versión, lo que significa que se seleccionaron las versiones más recientes. Si surge alguna incompatibilidad, especifica los números de versión para bloquear las versiones de trabajo.
app.yaml
Nuevas secciones para agregar
El entorno de ejecución de App Engine para Python 2 requiere paquetes de terceros específicos cuando se usan las API de Cloud, como Cloud NDB, es decir, grpcio
y setuptools
. Los usuarios de Python 2 deben enumerar las bibliotecas integradas como estas junto con una versión disponible en app.yaml
. Si aún no tienes una sección libraries
, crea una y agrega ambas bibliotecas como se muestra a continuación:
libraries:
- name: grpcio
version: latest
- name: setuptools
version: latest
Cuando migres tu app, es posible que ya tenga una sección libraries
. Si es así, y faltan grpcio
y setuptools
, solo agrégalos a tu sección libraries
existente.
Luego, nuestra app de ejemplo necesita la instancia de Cloud Memorystore y la información del conector de VPC, por lo que debes agregar las siguientes dos secciones nuevas a app.yaml
, sin importar qué entorno de ejecución de Python uses:
env_variables:
REDIS_HOST: 'YOUR_REDIS_HOST'
REDIS_PORT: 'YOUR_REDIS_PORT'
vpc_access_connector:
name: projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR
Eso es todo con respecto a las actualizaciones requeridas. Tu app.yaml
actualizado debería verse de la siguiente manera:
runtime: python27
threadsafe: yes
api_version: 1
handlers:
- url: /.*
script: main.app
libraries:
- name: grpcio
version: 1.0.0
- name: setuptools
version: 36.6.0
env_variables:
REDIS_HOST: 'YOUR_REDIS_HOST'
REDIS_PORT: 'YOUR_REDIS_PORT'
vpc_access_connector:
name: projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR
A continuación, se muestra un "antes y después" Con ejemplos de las actualizaciones que debes aplicar a app.yaml
:
*Diferencias de Python 3
Esta sección es opcional y solo si tienes que realizar la portabilidad a Python 3. Para hacerlo, debes realizar una serie de cambios en la configuración de Python 2. Omite esta sección si no deseas realizar la actualización en este momento.
Ni threadsafe
ni api_version
se usan para el entorno de ejecución de Python 3, así que borra ambas opciones de configuración. El entorno de ejecución más reciente de App Engine no admite bibliotecas de terceros integradas ni la copia de bibliotecas no integradas. El único requisito para los paquetes de terceros es incluirlos en una lista en requirements.txt
. Como resultado, se puede borrar toda la sección libraries
de app.yaml
.
Además, el entorno de ejecución de Python 3 requiere el uso de frameworks web que hagan su propio enrutamiento; por eso, les mostramos a los desarrolladores cómo migrar de webp2 a Flask en el módulo 1. Como resultado, todos los controladores de secuencia de comandos se deben cambiar a auto
. Como esta app no entrega archivos estáticos, es "sin sentido" para tener controladores en la lista (ya que todos son auto
), por lo que también se puede quitar toda la sección handlers
. Como resultado, tu nuevo app.yaml
abreviado ajustado para Python 3 debería acortarse de la siguiente manera:
runtime: python39
env_variables:
REDIS_HOST: 'YOUR_REDIS_HOST'
REDIS_PORT: 'YOUR_REDIS_PORT'
vpc_access_connector:
name: projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR
A continuación, se resumen las diferencias en app.yaml
cuando se realiza la portabilidad a Python 3:
- Borrar los parámetros de configuración de
threadsafe
yapi_version
- Borrar la sección
libraries
- Borrar la sección
handlers
(o solo los controladoresscript
si tu app entrega archivos estáticos)
Reemplaza los valores
Los valores de las secciones nuevas de Memorystore y el conector de VPC son solo marcadores de posición. Reemplaza esos valores en mayúscula (YOUR_REDIS_HOST, YOUR_REDIS_PORT, PROJECT_ID, REGION, CONNECTOR_NAME
) por los valores guardados desde cuando creaste esos recursos anteriormente. Con respecto a tu instancia de Memorystore, asegúrate de usar HOST
(no RESERVED_IP
) y PORT
. A continuación, se muestra una forma rápida de línea de comandos de obtener HOST
y PORT
, suponiendo que el nombre de instancia demo-ms
y REGION
es us-central1
:
$ gcloud redis instances describe demo-ms --region us-central1 \ --format "value(host,port)" 10.251.161.51 6379
Si la dirección IP de nuestra instancia de Redis de ejemplo era 10.10.10.10
con el puerto 6379
de nuestro proyecto my-project
, ubicado en la región us-central1
con un nombre de conector de VPC de demo-vpc
, estas secciones en app.yaml
se verán de la siguiente manera:
env_variables:
REDIS_HOST: '10.10.10.10'
REDIS_PORT: '6379'
vpc_access_connector:
name: projects/my-project/locations/us-central1/connectors/demo-vpc
Crea o actualiza appengine_config.py
Cómo agregar compatibilidad con bibliotecas de terceros integradas
Al igual que hicimos antes con app.yaml
, agrega el uso de las bibliotecas grpcio
y setuptools
. Modifica appengine_config.py
para que admita bibliotecas de terceros integradas. Si esto te resulta familiar, es porque también se requería en el módulo 2 cuando se migraba de ndb
de App Engine a Cloud NBS. El cambio exacto requerido es agregar la carpeta lib
al conjunto de trabajo setuptools.pkg_resources
:
*Diferencias de Python 3
Esta sección es opcional y solo si tienes que realizar la portabilidad a Python 3. Uno de los bienvenidos cambios de segunda generación de App Engine es que ya no es necesario copiar (a veces denominada "proveedor") de paquetes de terceros (no integrados) ni hacer referencia a paquetes de terceros integrados en app.yaml
, lo que significa que puedes borrar todo el archivo appengine_config.py
.
6. Actualizar archivos de la aplicación
Solo hay un archivo de la aplicación, main.py
, por lo que todos los cambios en esta sección afectan solo a ese archivo. Ofrecemos una representación visual de los cambios que haremos para migrar esta aplicación a Cloud Memorystore. Solo tiene fines ilustrativos y no pretende realizar un análisis minucioso. Todo el trabajo está en los cambios que hacemos en el código.
Veamos esto una sección a la vez, empezando por la parte superior.
Actualizar importaciones
La sección de importación en main.py
para el módulo 12 usa Cloud NDB y Cloud Tasks. estas son sus importaciones:
ANTES:
from flask import Flask, render_template, request
from google.appengine.api import memcache
from google.appengine.ext import ndb
Para cambiar a Memorystore, es necesario leer las variables de entorno, por lo que necesitamos el módulo os
de Python y redis
, el cliente de Redis para Python. Dado que Redis no puede almacenar en caché objetos de Python, ordena la lista de visitas más recientes usando pickle
, así que impórtalo también. Un beneficio de Memcache es que la serialización de objetos se produce automáticamente, mientras que Memorystore es algo más "DIY". Por último, actualiza de App Engine ndb
a Cloud NBS reemplazando google.appengine.ext.ndb
con google.cloud.ndb
. Después de estos cambios, tus importaciones deberían verse de la siguiente manera:
DESPUÉS:
import os
import pickle
from flask import Flask, render_template, request
from google.cloud import ndb
import redis
Actualizar inicialización
La inicialización del módulo 12 consiste en crear una instancia del objeto de aplicación de Flask app
y establecer una constante para una hora de almacenamiento en caché:
ANTES:
app = Flask(__name__)
HOUR = 3600
Para usar las APIs de Cloud, se necesita un cliente, así que crea una instancia de un cliente de Cloud NDB justo después de Flask. A continuación, obtén la dirección IP y el número de puerto de la instancia de Memorystore de las variables de entorno que configuraste en app.yaml
. Con esa información, crea una instancia de un cliente de Redis. Así se verá tu código después de esas actualizaciones:
DESPUÉS:
app = Flask(__name__)
ds_client = ndb.Client()
HOUR = 3600
REDIS_HOST = os.environ.get('REDIS_HOST', 'localhost')
REDIS_PORT = os.environ.get('REDIS_PORT', '6379')
REDIS = redis.Redis(host=REDIS_HOST, port=REDIS_PORT)
*Migración de Python 3
Esta sección es opcional si estás comenzando desde la versión de Python 3 de la app del módulo 12. Si es así, hay varios cambios necesarios relacionados con las importaciones y la inicialización.
En primer lugar, dado que Memcache es un servicio empaquetado de App Engine, su uso en una app de Python 3 requiere el SDK de App Engine, en el que se debe unir específicamente la aplicación WSGI (además de otra configuración necesaria):
ANTES:
from flask import Flask, render_template, request
from google.appengine.api import memcache, wrap_wsgi_app
from google.appengine.ext import ndb
app = Flask(__name__)
app.wsgi_app = wrap_wsgi_app(app.wsgi_app)
HOUR = 3600
Debido a que estamos migrando a Cloud Memorystore (no un servicio empaquetado en App Engine como Memcache), se debe quitar el uso del SDK. Esto es sencillo, ya que solo borrarás toda la línea que importa memcache
y wrap_wsgi_app
. También borra la línea que llama a wrap_wsgi_app()
. Estas actualizaciones dejan esta parte de la app (en realidad, la app completa) idéntica a la versión de Python 2.
DESPUÉS:
import os
import pickle
from flask import Flask, render_template, request
from google.cloud import ndb
import redis
app = Flask(__name__)
ds_client = ndb.Client()
HOUR = 3600
REDIS_HOST = os.environ.get('REDIS_HOST', 'localhost')
REDIS_PORT = os.environ.get('REDIS_PORT', '6379')
REDIS = redis.Redis(host=REDIS_HOST, port=REDIS_PORT)
Por último, quita el uso del SDK de app.yaml
(borra la línea: app_engine_apis: true
) y requirements.txt
(borra la línea: appengine-python-standard
).
Migra a Cloud Memorystore (y Cloud NDB)
El modelo de datos de Cloud NDB está diseñado para ser compatible con los ndb
de App Engine, lo que significa que la definición de los objetos Visit
es la misma. Para imitar la migración del módulo 2 a Cloud NDB, todas las llamadas de Datastore en store_visit()
y fetch_visits()
se aumentan y se incorporan en un nuevo bloque with
(ya que se requiere el uso del administrador de contexto de Cloud NDB). Estas son esas llamadas antes del cambio:
ANTES:
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
'get most recent visits'
return Visit.query().order(-Visit.timestamp).fetch(limit)
Agrega un bloque with ds_client.context()
a ambas funciones y coloca las llamadas a Datastore dentro (con sangría). En este caso, no es necesario realizar cambios para las llamadas en sí:
DESPUÉS:
def store_visit(remote_addr, user_agent):
'create new Visit entity in Datastore'
with ds_client.context():
Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()
def fetch_visits(limit):
'get most recent visits'
with ds_client.context():
return Visit.query().order(-Visit.timestamp).fetch(limit)
A continuación, veamos los cambios
de almacenamiento en caché. Esta es la función main()
del módulo 12:
ANTES:
@app.route('/')
def root():
'main application (GET) handler'
# check for (hour-)cached visits
ip_addr, usr_agt = request.remote_addr, request.user_agent
visitor = '{}: {}'.format(ip_addr, usr_agt)
visits = memcache.get('visits')
# register visit & run DB query if cache empty or new visitor
if not visits or visits[0].visitor != visitor:
store_visit(ip_addr, usr_agt)
visits = list(fetch_visits(10))
memcache.set('visits', visits, HOUR) # set() not add()
return render_template('index.html', visits=visits)
Redis tiene la función "get" y "establecer" al igual que Memcache. Todo lo que hacemos es intercambiar las respectivas bibliotecas cliente, ¿verdad? Estuviste cerca. Como se mencionó antes, no podemos almacenar en caché una lista de Python con Redis (porque primero debe serializarse, algo que Memcache se encarga automáticamente), por lo tanto, en la llamada a set()
, "pickle" las visitas en una cadena con pickle.dumps()
. Del mismo modo, cuando recuperes las visitas de la caché, deberás desenmarañarlas con pickle.loads()
justo después de get()
. A continuación, se muestra el controlador principal después de implementar esos cambios:
DESPUÉS:
@app.route('/')
def root():
'main application (GET) handler'
# check for (hour-)cached visits
ip_addr, usr_agt = request.remote_addr, request.user_agent
visitor = '{}: {}'.format(ip_addr, usr_agt)
rsp = REDIS.get('visits')
visits = pickle.loads(rsp) if rsp else None
# register visit & run DB query if cache empty or new visitor
if not visits or visits[0].visitor != visitor:
store_visit(ip_addr, usr_agt)
visits = list(fetch_visits(10))
REDIS.set('visits', pickle.dumps(visits), ex=HOUR)
return render_template('index.html', visits=visits)
Con esto concluye los cambios requeridos en main.py
para convertir el uso de Memcache de la app de ejemplo en Cloud Memorystore. ¿Qué ocurre con la plantilla HTML y la portabilidad a Python 3?
¿Quieres actualizar el archivo de plantilla HTML y el puerto a Python 3?
¡Sorpresa! No hay nada que hacer aquí, ya que la aplicación se diseñó para ejecutarse tanto en Python 2 como en Python 3 sin cambios en el código ni bibliotecas de compatibilidad. Encontrarás main.py
. idéntico en mod13a
(2.x) y mod13b
(3.x) "FINISH" individuales. Lo mismo ocurre con requirements.txt
, excepto por las diferencias en los números de versión (si se usan). Como la interfaz de usuario permanece igual, templates/index.html
tampoco se actualiza.
Todo lo necesario para ejecutar esta app en Python 3 de App Engine se completó antes en la configuración: se quitaron directivas innecesarias de app.yaml
y se borraron las carpetas appengine_config.py
y lib
, ya que no se usan en Python 3.
7. Resumen/limpieza
En esta sección, se finaliza este codelab implementando la app y verificando que funcione según lo previsto y en cualquier resultado reflejado. Después de validar la app, realiza una limpieza y considera los pasos siguientes.
Implementa y verifica la aplicación
La última verificación es siempre implementar la app de ejemplo. Si eres desarrollador de Python 2, borra y reinstala lib
con los siguientes comandos. (Si tienes Python 2 y 3 instalados en tu sistema, es posible que debas ejecutar pip2
de manera explícita en su lugar).
rm -rf ./lib pip install -t lib -r requirements.txt
Tanto los desarrolladores de Python 2 como los de Python 3 ahora deberían implementar sus aplicaciones con lo siguiente:
gcloud app deploy
Como simplemente reorganizaste los elementos internos para un servicio de almacenamiento en caché completamente diferente, la app debería funcionar de manera idéntica a la del Módulo 12:
Con este paso se completa el codelab. Te invitamos a comparar tu app de ejemplo actualizada con cualquiera de las carpetas del Módulo 13: mod13a
(Python 2) o mod13b
(Python 3).
Limpia
General
Si ya terminaste, te recomendamos que inhabilites la aplicación de App Engine para evitar que se te facture. Sin embargo, si deseas probar o experimentar un poco más, la plataforma de App Engine tiene una cuota gratuita y, siempre y cuando no superes ese nivel de uso, no se te debería cobrar. Eso es para procesamiento, pero es posible que también se apliquen cargos por servicios relevantes de App Engine, así que consulta la página de precios para obtener más información. Si esta migración implica otros servicios de Cloud, estos se facturan por separado. En ambos casos, si corresponde, consulta la sección "Específico de este codelab" a continuación.
Para una divulgación completa, la implementación en una plataforma de procesamiento sin servidores de Google Cloud, como App Engine, genera costos menores de compilación y almacenamiento. Cloud Build tiene su propia cuota gratuita, al igual que Cloud Storage. El almacenamiento de esa imagen ocupa parte de esa cuota. Sin embargo, es posible que vivas en una región que no cuenta con ese nivel gratuito, así que ten en cuenta el uso que haces del almacenamiento para minimizar posibles costos. “Carpetas” específicas de Cloud Storage que debes revisar incluyen
console.cloud.google.com/storage/browser/LOC.artifacts.PROJECT_ID.appspot.com/containers/images
console.cloud.google.com/storage/browser/staging.PROJECT_ID.appspot.com
- Los vínculos de almacenamiento anteriores dependen de tu
PROJECT_ID
y *LOC
*; por ejemplo, "us
" si tu app está alojada en EE.UU.
Por otro lado, si no vas a continuar con esta aplicación o algún otro codelab de migración relacionado y quieres borrar todo por completo, cierra tu proyecto.
Información específica de este codelab
Los servicios que se indican a continuación son exclusivos de este codelab. Consulta la documentación de cada producto para obtener más información:
- Cloud Memorystore requiere instancias y no tiene un nivel gratuito. Para obtener más información sobre los costos de uso, consulta su página de precios.
- Los conectores de Acceso a VPC sin servidores de Cloud requieren instancias y no tienen un nivel gratuito. Para obtener más información sobre los costos de uso, consulta su sección en la página de precios de VPC de Cloud.
- Cloud Datastore (Cloud Firestore en modo Datastore) tiene un nivel gratuito. consulta su página de precios para obtener más información.
En este instructivo, se incluyó el uso de cuatro productos de Cloud:
- App Engine
- Cloud Datastore
- Cloud Memorystore
- VPC de Cloud
A continuación, se incluyen instrucciones para liberar estos recursos y evitar o minimizar los cargos de facturación.
Cierra la instancia de Memorystore y el conector de VPC
Estos son los productos sin un nivel gratuito, por lo que estás generando facturación en este momento. Si no cierras tu proyecto de Cloud (consulta la siguiente sección), debes borrar tanto tu instancia de Memorystore como el conector de VPC para detener la facturación. Al igual que cuando creaste estos recursos, también puedes liberarlos desde la consola de Cloud o desde la línea de comandos.
Desde la consola de Cloud
Para borrar la instancia de Memorystore, vuelve al panel de Memorystore y haz clic en el ID de la instancia:
Cuando estés en la página de detalles de la instancia, haz clic en “Borrar”. y confirma lo siguiente:
Para borrar el conector de VPC, ve a su panel, selecciona la casilla de verificación junto al conector que deseas borrar y, luego, haz clic en “Borrar” y confirma lo siguiente:
Desde la línea de comandos
Con el siguiente par de comandos de gcloud
, se borran la instancia de Memorystore y el conector de VPC, respectivamente:
gcloud redis instances delete INSTANCE --region REGION
gcloud compute networks vpc-access connectors delete CONNECTOR --region REGION
Si no configuraste tu ID del proyecto con gcloud config set project
, es posible que debas proporcionar --project PROJECT_ID
. Si tu instancia de Memorystore se llama demo-ms
y el conector de VPC se llama demo-vpc
, y ambos se encuentran en la región us-central1
, emite el siguiente par de comandos y confirma lo siguiente:
$ gcloud redis instances delete demo-ms --region us-central1 You are about to delete instance [demo-ms] in [us-central1]. Any associated data will be lost. Do you want to continue (Y/n)? Delete request issued for: [demo-ms] Waiting for operation [projects/PROJECT/locations/REGION/operations/operation-aaaaa-bbbbb-ccccc-ddddd] to complete...done. Deleted instance [demo-ms]. $ $ gcloud compute networks vpc-access connectors delete demo-vpc --region us-central1 You are about to delete connector [demo-vpc] in [us-central1]. Any associated data will be lost. Do you want to continue (Y/n)? Delete request issued for: [demo-vpc] Waiting for operation [projects/PROJECT/locations/REGION/operations/aaaaa-bbbb-cccc-dddd-eeeee] to complete...done. Deleted connector [demo-vpc].
Cada solicitud tarda unos minutos en ejecutarse. Estos pasos son opcionales si decides cerrar todo el proyecto de Cloud como se describió antes. Sin embargo, se te seguirá cobrando hasta que se complete el proceso de cierre.
Próximos pasos
Más allá de este instructivo, otros módulos de migración que se enfocan en alejarse de los servicios en paquetes heredados que se deben considerar incluyen los siguientes:
- Módulo 2: migrar de
ndb
de App Engine a Cloud NDB - Módulos del 7 al 9: Migra de las tareas push de la lista de tareas en cola de App Engine a Cloud Tasks
- Módulos del 12 al 13: Migra de Memcache de App Engine a Cloud Memorystore
- Módulos del 15 al 16: Migra de Blobstore de App Engine a Cloud Storage
- Módulos del 18 al 19: Migra de la lista de tareas en cola de App Engine (tareas de extracción) a Cloud Pub/Sub.
App Engine ya no es la única plataforma sin servidores en Google Cloud. Si tienes una aplicación pequeña de App Engine o una con funcionalidad limitada y deseas convertirla en un microservicio independiente, o si deseas dividir una aplicación monolítica en varios componentes reutilizables, estas son buenas razones para considerar cambiar a Cloud Functions. Si la creación de contenedores se volvió parte del flujo de trabajo de desarrollo de tu aplicación, en especial si consta de una canalización de CI/CD (integración continua/entrega o implementación continuas), considera migrar a Cloud Run. Estas situaciones se abordan en los siguientes módulos:
- Migra de App Engine a Cloud Functions: consulta el Módulo 11.
- Migra de App Engine a Cloud Run. Consulta el Módulo 4 para alojar tu app en contenedores con Docker, o el Módulo 5 para hacerlo sin contenedores, conocimiento sobre Docker ni
Dockerfile
.
Cambiar a otra plataforma sin servidores es opcional, y te recomendamos que consideres las mejores opciones para tus apps y casos de uso antes de realizar cualquier cambio.
Independientemente del módulo de migración que consideres a continuación, puedes acceder a todo el contenido de Serverless Migration Station (codelabs, videos, código fuente [si está disponible]) a través de su repositorio de código abierto. El README
del repositorio también proporciona orientación sobre qué migraciones considerar y cualquier "orden" relevante. de los módulos de migración.
8. Recursos adicionales
A continuación, se incluyen recursos adicionales para los desarrolladores que exploran este módulo o uno relacionado, así como productos relacionados. Esto incluye lugares donde enviar comentarios sobre este contenido, vínculos al código y varios documentos que pueden resultarte útiles.
Problemas o comentarios sobre Codelabs
Si encuentras algún problema con este Codelab, primero busca el problema antes de enviarlo. Vínculos para buscar y crear problemas nuevos:
Recursos de migración
En la siguiente tabla, encontrarás los vínculos a las carpetas de repo del Módulo 12 (COMENZAR) y Módulo 13 (FINALIZAR). También puedes acceder a ellos desde el repositorio para todas las migraciones del codelab de App Engine. Puedes clonar o descargar un archivo ZIP.
Codelab | Python 2 | Python 3 |
Módulo 13 (este codelab) |
Referencias en línea
A continuación, hay recursos en línea que pueden ser relevantes para este tutorial:
App Engine
- Documentación de App Engine
- Entorno de ejecución de App Engine (entorno estándar) para Python 2
- Usa las bibliotecas integradas de App Engine en Python 2 de App Engine
- Entorno de ejecución de App Engine (entorno estándar) para Python 3
- Diferencias entre Python 2 y 3 entornos de ejecución de App Engine (entorno estándar)
- Guía de migración de Python 2 a 3 de App Engine (entorno estándar)
- Información de precios y cuotas de App Engine
App Engine NDB y Cloud NDB
- Descripción general de App Engine NDB
- Uso de App Engine NDB Datastore
- Documentos de NDB de Google Cloud
- Repositorio de NDB de Google Cloud
- Información de precios de Cloud Datastore
Memcache de App Engine y Cloud Memorystore
- Descripción general de Memcache de App Engine
- Referencia de
memcache
para Python 2 en App Engine - Referencia de
memcache
para Python 3 en App Engine - Guía de migración de
memcache
de App Engine a Cloud Memorystore - Documentación de Cloud Memorystore
- Documentación de Cloud Memorystore para Redis
- Información de precios de Cloud Memorystore para Redis
- Versiones de Redis compatibles con Cloud Memorystore
- Página principal de Cloud Memorystore
- Crea una instancia nueva de Memorystore en la consola de Cloud
- Página principal del cliente de Redis para Python
- Documentación de la biblioteca cliente de Redis para Python
VPC de Cloud
- Documentos de VPC de Google Cloud
- Página principal de la VPC de Google Cloud
- Información de precios de VPC de Cloud
- Crea un nuevo conector de Acceso a VPC sin servidores en la consola de Cloud
Otra información de Cloud
- Python en Google Cloud Platform
- Bibliotecas cliente de Python de Google Cloud
- Google Cloud “Siempre gratuito” nivel
- SDK de Google Cloud (herramienta de línea de comandos de
gcloud
) - Toda la documentación de Google Cloud
Licencia
Este trabajo cuenta con una licencia Atribución 2.0 Genérica de Creative Commons.