Migrar do Memcache do App Engine para o Cloud Memorystore (módulo 13)

1. Visão geral

A série de codelabs da estação de migração sem servidor (tutoriais práticos e individualizados) e os vídeos relacionados têm como objetivo ajudar desenvolvedores sem servidor do Google Cloud a modernizar apps, orientando-os em uma ou mais migrações, principalmente para evitar serviços legados. Isso torna seus apps mais portáteis e oferece mais opções e flexibilidade, o que permite a integração e o acesso a uma variedade maior de produtos do Cloud e o upgrade para versões de idiomas mais recentes com mais facilidade. Embora inicialmente voltada para os primeiros usuários do Cloud, principalmente desenvolvedores do App Engine (ambiente padrão), esta série é ampla o suficiente para incluir outras plataformas sem servidor, como o Cloud Functions e o Cloud Run, ou outros lugares, se aplicável.

O objetivo deste codelab é mostrar aos desenvolvedores do App Engine em Python 2 como migrar do Memcache do App Engine para o Cloud Memorystore (para Redis). Há também uma migração implícita do App Engine ndb para o Cloud Node, mas ela é abordada principalmente no codelab do módulo 2. confira mais informações passo a passo.

Você vai aprender a

  • Configurar uma instância do Cloud Memorystore (no Console do Cloud ou na ferramenta gcloud)
  • Configurar um conector de acesso VPC sem servidor do Cloud (no Console do Cloud ou na ferramenta gcloud)
  • Migrar do Memcache do App Engine para o Cloud Memorystore
  • Implementar o armazenamento em cache com o Cloud Memorystore em um aplicativo de amostra
  • Migrar do App Engine ndb para o Cloud NDB

O que é necessário

Pesquisa

Como você usará este tutorial?

Apenas ler o documento Ler e fazer os exercícios

Como você classificaria sua experiência com Python?

Iniciante Intermediário Proficiente

Como você classificaria sua experiência de uso dos serviços do Google Cloud?

Iniciante Intermediário Proficiente

2. Contexto

Este codelab demonstra como migrar um aplicativo de amostra do App Engine Memcache (e do MapReduce) para o Cloud Memorystore (e o Cloud serviço). Esse processo envolve a substituição de dependências nos serviços agrupados no App Engine, o que aumenta a portabilidade dos aplicativos. Você pode optar por permanecer no App Engine ou considerar mudar para qualquer uma das alternativas descritas anteriormente.

Essa migração requer mais esforço em comparação com as outras desta série. A substituição recomendada para o Memcache do App Engine é o Cloud Memorystore, um serviço de armazenamento em cache totalmente gerenciado e baseado em nuvem. O Memorystore oferece suporte a um par de mecanismos conhecidos de armazenamento em cache de código aberto, o Redis e o Memcached. Este módulo de migração usa o Cloud Memorystore para Redis. Saiba mais na Visão geral do Memorystore e do Redis.

Como o Memorystore exige um servidor em execução, o Cloud VPC também é necessário. Especificamente, é necessário criar um conector de acesso VPC sem servidor para que o aplicativo do App Engine possa se conectar à instância do Memorystore pelo endereço IP particular. Ao concluir este exercício, você terá atualizado o aplicativo para que, embora ele se comporte como antes, o Cloud Memorystore será o serviço de armazenamento em cache, substituindo o serviço de Memcache do App Engine.

Este tutorial começa com o aplicativo de exemplo do Módulo 12 em Python 2, seguido por um upgrade secundário adicional e opcional para o Python 3. Se você já sabe como acessar os serviços incluídos no App Engine no Python 3 usando o SDK do App Engine para Python 3, comece com a versão para Python 3 do app de exemplo do Módulo 12. Isso implica a remoção do uso do SDK, já que o Memorystore não é um serviço incluído no App Engine. Aprender a usar o SDK do App Engine para Python 3 está fora do escopo deste tutorial.

Este tutorial apresenta as seguintes etapas principais:

  1. Configuração/pré-trabalho
  2. Configurar serviços de armazenamento em cache
  3. Atualizar os arquivos de configuração
  4. Atualizar aplicativo principal

3. Configuração/pré-trabalho

Preparar projeto do Cloud

Recomendamos reutilizar o mesmo projeto usado para concluir o codelab do módulo 12. Outra opção é criar um novo projeto ou reutilizar um projeto existente. Cada codelab desta série tem um "INÍCIO" (o código de referência para começar) e um "FINISH" (o app migrado). O código FINISH é fornecido para que você possa comparar suas soluções com as nossas caso tenha problemas. Você pode reverter para START de novo se algo der errado. Esses pontos de verificação são projetados para garantir que você tenha sucesso ao aprender como realizar as migrações.

Seja qual for o projeto do Cloud usado, verifique se ele tem uma conta de faturamento ativa. Verifique também se o App Engine está ativado. Leia estes tutoriais para entender as implicações gerais de custo. No entanto, ao contrário de outros itens desta série, este codelab usa recursos do Cloud que não têm um nível sem custo financeiro. Portanto, alguns custos serão gerados para a conclusão do exercício. Informações de custo mais específicas serão fornecidas juntamente com recomendações para redução de uso, incluindo instruções no final sobre como liberar recursos para minimizar cobranças de cobrança.

Receber app de amostra do valor de referência

A partir do código de referência do Módulo 12 que estamos começando, este codelab orienta você na migração em detalhes. Ao concluir, você terá um app funcional do Módulo 13 que se assemelha ao código de uma das pastas FINISH. Confira esses recursos:

A pasta START deve conter os seguintes arquivos:

$ ls
README.md               app.yaml                main.py                 requirements.txt        templates                

Se você estiver começando pela versão do Python 2, também vai haver um arquivo appengine_config.py e possivelmente uma pasta lib se tiver concluído o codelab do Módulo 12.

(Re)implantar o app Módulo 12

Suas etapas de pré-trabalho restantes:

  1. Familiarize-se com a ferramenta de linha de comando gcloud (se necessário).
  2. (Re)implantar o código do Módulo 12 no App Engine (se necessário)

Os usuários do Python 2 precisam excluir e reinstalar a pasta lib com estes comandos:

rm -rf ./lib; pip install -t lib -r requirements.txt                

Agora todos (usuários de Python 2 e 3) devem fazer upload do código para o App Engine com este comando:

gcloud app deploy                

Após a implantação, confirme se o app tem a aparência e o funcionamento do app no Módulo 12, um app da Web que rastreia visitas, armazenando-as em cache para o mesmo usuário por uma hora:

dfe56a02ae59ddd8.png

Como as visitas mais recentes são armazenadas em cache, as atualizações da página devem carregar rapidamente.

4. Configurar serviços de armazenamento em cache

O Cloud Memorystore não funciona sem servidor. Uma instância é obrigatória. nesse caso, um executando o Redis. Ao contrário do Memcache, o Memorystore é um produto independente do Cloud e não tem um nível sem custo financeiro. Por isso, verifique as informações de preços do Memorystore para Redis antes de continuar. Para minimizar os custos desse exercício, recomendamos a menor quantidade de recursos para operar: um nível de serviço básico e uma capacidade de 1 GB.

A instância do Memorystore está em uma rede diferente do aplicativo do App Engine (instâncias). É por isso que é preciso criar um conector de acesso VPC sem servidor para que o App Engine possa acessar os recursos do Memorystore. Para minimizar os custos da VPC, opte pelo tipo de instância (f1-micro) e pelo menor número de instâncias a serem solicitadas (sugerimos no mínimo 2, máximo de 3). Confira também a página de informações sobre preços da VPC.

Repetimos essas recomendações para reduzir custos à medida que orientamos você na criação de cada recurso necessário. Além disso, ao criar recursos do Memorystore e da VPC no console do Cloud, você verá a calculadora de preços de cada produto no canto superior direito, que fornece uma estimativa de custo mensal (consulte a ilustração abaixo). Esses valores serão ajustados automaticamente se você alterar as opções. Aproximadamente, isto é o que você deve ver:

7eb35ebf7248c010.png

Os dois recursos são necessários, e não importa qual deles você cria primeiro. Se você criar a instância do Memorystore primeiro, o aplicativo do App Engine não poderá acessá-la sem o conector de VPC. Da mesma forma, se você criar o conector VPC primeiro, não haverá nada nessa rede para o aplicativo do App Engine se comunicar. Neste tutorial, ensinamos como criar a instância do Memorystore primeiro e depois o conector de VPC.

Quando os dois recursos estiverem on-line, você vai adicionar as informações relevantes ao app.yaml para que o app possa acessar o cache. Também é possível consultar os guias do Python 2 ou Python 3 na documentação oficial. Também vale a pena consultar o guia de armazenamento em cache de dados na página de migração do Cloud NBS ( Python 2 ou Python 3).

Criar uma instância do Cloud Memorystore

Como o Cloud Memorystore não tem um nível sem custo financeiro, recomendamos alocar a menor quantidade de recursos para concluir o codelab. Use estas configurações para manter os custos em um nível mínimo:

  • Selecione o nível de serviço mais baixo: Básico (padrão do console: "Padrão", gcloud como padrão: "Básico").
  • Escolha a menor quantidade de armazenamento: 1 GB (padrão do console: 16 GB, gcloud padrão: 1 GB).
  • Normalmente, as versões mais recentes de qualquer software exigem a maior quantidade de recursos, mas selecionar a versão mais antiga também não é recomendado. A segunda versão mais recente atualmente é a versão do Redis 5.0 (padrão do console: 6.x).

Com essas configurações em mente, a próxima seção mostra como criar a instância no console do Cloud. Se preferir fazer isso na linha de comando, pule para a próxima.

No Console do Cloud

Acesse a página do Cloud Memorystore no console do Cloud. Talvez você precise fornecer informações de faturamento. Se você ainda não ativou o Memorystore, será necessário fazer isso:

68318997e3105db6.png

Depois de ativá-lo (e possivelmente junto com o faturamento), você chegará ao painel do Memorystore. É aqui que você pode ver todas as instâncias criadas no seu projeto. O projeto mostrado abaixo não tem nenhuma. É por isso que a mensagem "No rows to display" é exibida. Para criar uma instância do Memorystore, clique em Criar instância na parte de cima:

63547aa575838a36.png

Esta página apresenta um formulário a ser preenchido com as configurações desejadas para criar a instância do Memorystore:

b77d927287fdf4c7.png

Para manter os custos baixos para este tutorial e o app de exemplo dele, siga as recomendações abordadas anteriormente. Depois de escolher as opções, clique em Criar. O processo de criação leva vários minutos. Quando terminar, copie o endereço IP da instância e o número da porta para adicionar a app.yaml.

Na linha de comando,

Embora seja visualmente informativo criar instâncias do Memorystore no console do Cloud, alguns preferem a linha de comando. Confira se o gcloud está instalado e inicializado antes de continuar.

Assim como no console do Cloud, é necessário ativar o Cloud Memorystore para Redis. Emita o comando gcloud services enable redis.googleapis.com e aguarde a conclusão, como neste exemplo:

$ gcloud services enable redis.googleapis.com
Operation "operations/acat.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.

Se o serviço já estiver ativado, executar o comando (novamente) não terá efeitos colaterais (negativos). Com o serviço ativado, vamos criar uma instância do Memorystore. O comando vai ficar assim:

gcloud redis instances create NAME --redis-version VERSION \
    --region REGION --project PROJECT_ID

Escolha um nome para sua instância do Memorystore. este laboratório usa "demo-ms" como o nome junto com um ID de projeto de "my-project". A região deste app de exemplo é us-central1 (igual a us-central), mas é possível usar uma região mais próxima de você se a latência for uma preocupação. Selecione a mesma região do seu aplicativo do App Engine. É possível selecionar a versão do Redis que você preferir, mas estamos usando a versão 5, conforme recomendado anteriormente. Com base nessas configurações, este é o comando que você emitiria (junto da saída associada):

$ 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].

Ao contrário dos padrões do Console do Cloud, o padrão de gcloud é ter recursos mínimos. O resultado é que o nível de serviço e a quantidade de armazenamento não eram necessários naquele comando. A criação de uma instância do Memorystore leva vários minutos. Após a conclusão, anote o endereço IP e o número da porta da instância, porque eles serão adicionados ao app.yaml em breve.

Confirmar criação da instância

No console do Cloud ou na linha de comando

Se você criou a instância no console do Cloud ou na linha de comando, confirme se ela está disponível e pronta para uso com este comando: gcloud redis instances list --region REGION

Este é o comando para verificar instâncias na região us-central1 e a saída esperada mostrando a instância que acabamos de criar:

$ 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

Quando as informações da instância ou a configuração do app forem solicitadas, use HOST e PORT (não RESERVED_IP). O painel do Cloud Memorystore no console do Cloud agora exibirá essa instância:

c5a6948ec1c056ed.png

Da máquina virtual do Compute Engine

Se você tem uma máquina virtual (VM) do Compute Engine, também pode enviar comandos diretos à instância do Memorystore de uma VM para confirmar que ela está funcionando. Esteja ciente de que o uso de uma VM pode ter custos associados independentemente dos recursos que você já usa.

Criar conector de acesso VPC sem servidor

Assim como acontece com o Cloud Memorystore, é possível criar o conector sem servidor do Cloud VPC no Console do Cloud ou na linha de comando. Da mesma forma, a VPC do Cloud não tem nível sem custo financeiro. Portanto, recomendamos alocar a menor quantidade de recursos para concluir o codelab para manter os custos no mínimo, e isso pode ser feito com estas configurações:

  • Selecione o menor número máximo de instâncias: 3 (console e gcloud padrão: 10)
  • Escolha o tipo de máquina de menor custo: f1-micro (padrão do console: e2-micro, sem o padrão gcloud)

Na próxima seção, vamos mostrar como criar o conector no console do Cloud usando as configurações de VPC do Cloud acima. Se preferir fazer isso na linha de comando, pule para a próxima seção.

No console do Cloud

Acesse "Acesso à VPC sem servidor" do Cloud Networking no console do Cloud. Talvez você precise inserir informações de faturamento. Se você ainda não ativou a API, vai receber uma solicitação para fazer isso:

e3b9c0651de25e97.png

Depois de ativar a API (e possivelmente junto com o faturamento), você vai ver o painel que mostra todos os conectores de VPC criados. O projeto usado na captura de tela abaixo não tem nenhum, por isso diz “Nenhuma linha para exibir”. No console, clique em Criar conector na parte superior:

b74b49b9d73b7dcf.png

Preencha o formulário com as configurações desejadas:

6b26b2aafa719f73.png

Escolha as configurações apropriadas para seus próprios aplicativos. Para este tutorial e o app de exemplo dele com necessidades mínimas, faz sentido minimizar os custos. Portanto, siga as recomendações abordadas anteriormente. Depois de escolher as opções, clique em Criar. A solicitação de um conector de VPC vai levar alguns minutos para ser concluída.

Na linha de comando

Antes de criar um conector VPC, ative a API Serverless VPC Access. Você vai ver uma saída semelhante depois de executar o comando a seguir:

$ gcloud services enable vpcaccess.googleapis.com
Operation "operations/acf.p2-aaa-bbb-ccc-ddd-eee-ffffff" finished successfully.

Com a API ativada, um conector de VPC é criado com um comando parecido com este:

gcloud compute networks vpc-access connectors create CONNECTOR_NAME \
    --range 10.8.0.0/28 --region REGION --project PROJECT_ID

Escolha um nome para o conector e um endereço IP inicial do bloco CIDR /28 não utilizado. Neste tutorial, pressupomos o seguinte:

  • Project ID: my-project
  • Nome do conector de VPC: demo-vpc
  • Instâncias mínimas: 2 (padrão) e instâncias máximas: 3
  • Tipo de instância: f1-micro
  • Região: us-central1
  • Bloco CIDR IPv4: 10.8.0.0/28 (conforme recomendado no console do Cloud)

Se você executar o comando a seguir pensando nas suposições acima, espere um resultado semelhante ao mostrado abaixo:

$ 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].

O comando acima omite a especificação de valores padrão, como o mínimo de instâncias de 2 e uma rede chamada default. A criação de um conector de VPC leva vários minutos.

Confirmar criação do conector

Quando o processo for concluído, emita o seguinte comando gcloud, supondo que se trate da região us-central1, para confirmar que ele foi criado e está pronto para uso:

$ 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

Da mesma forma, o painel vai exibir o conector que você acabou de criar:

e03db2c8140ed014.png

Anote o ID do projeto do Cloud, o nome do conector de VPC e a região.

Agora que você criou os recursos adicionais do Cloud necessários, seja pela linha de comando ou no console, é hora de atualizar a configuração do aplicativo para que eles possam ser usados.

5. Atualizar os arquivos de configuração

A primeira etapa é fazer todas as atualizações necessárias nos arquivos de configuração. O principal objetivo deste codelab é ajudar os usuários do Python 2 a fazer a migração. No entanto, em cada seção abaixo, o conteúdo geralmente é seguido com informações sobre como fazer a migração para o Python 3.

requirements.txt

Nesta seção, adicionaremos pacotes para oferecer suporte ao Cloud Memorystore e ao Cloud Firestore. No caso do Cloud Memorystore para Redis, basta usar o cliente Redis padrão para Python (redis), já que não há uma biblioteca de cliente do Cloud Memorystore. Anexe redis e google-cloud-ndb a requirements.txt, unindo flask do Módulo 12:

flask
redis
google-cloud-ndb

Este arquivo requirements.txt não tem números de versão, o que significa que as versões mais recentes foram selecionadas. Se houver incompatibilidades, especifique os números de versão para bloquear as versões em funcionamento.

app.yaml

Novas seções para adicionar

O ambiente de execução do App Engine para Python 2 exige pacotes de terceiros específicos ao usar as APIs do Cloud, como o Cloud NBS, ou seja, grpcio e setuptools. Os usuários do Python 2 precisam listar bibliotecas integradas como essas junto com uma versão disponível em app.yaml. Se você ainda não tiver uma seção libraries, crie uma e adicione as duas bibliotecas da seguinte maneira:

libraries:
- name: grpcio
  version: latest
- name: setuptools
  version: latest

Ao migrar seu app, talvez ele já tenha uma seção libraries. Em caso afirmativo, e grpcio e setuptools estão ausentes, basta adicioná-los à seção libraries existente.

Em seguida, nosso app de exemplo precisa das informações da instância do Cloud Memorystore e do conector de VPC. Portanto, adicione as duas novas seções a seguir a app.yaml, independentemente do ambiente de execução do Python que você estiver usando:

env_variables:
    REDIS_HOST: 'YOUR_REDIS_HOST'
    REDIS_PORT: 'YOUR_REDIS_PORT'

vpc_access_connector:
    name: projects/PROJECT_ID/locations/REGION/connectors/CONNECTOR

Essas são as atualizações necessárias. Seu app.yaml atualizado ficará assim:

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

Confira abaixo um "antes e depois" ilustrando as atualizações que você deve aplicar a app.yaml:

ec2bb027a67debb6.png

*Diferenças do Python 3

Esta seção é opcional e somente se você estiver migrando para Python 3. Para isso, é preciso fazer várias alterações na configuração do Python 2. Pule esta seção se você não estiver fazendo upgrade no momento.

threadsafe e api_version não são usados no ambiente de execução do Python 3. Portanto, exclua essas duas configurações. O ambiente de execução mais recente do App Engine não oferece suporte a bibliotecas integradas de terceiros nem à cópia de bibliotecas não integradas. O único requisito para pacotes de terceiros é listá-los no requirements.txt. Como resultado, toda a seção libraries de app.yaml pode ser excluída.

Em seguida, o ambiente de execução do Python 3 exige o uso de frameworks da Web que façam roteamentos próprios. Por isso, mostramos aos desenvolvedores como migrar do webp2 para o Flask no módulo 1. Como resultado, todos os gerenciadores de script precisam ser alterados para auto. Como esse app não veicula arquivos estáticos, ele é "sem sentido" para ter gerenciadores listados (já que todos são auto), então toda a seção handlers também pode ser removida. Como resultado, a nova versão abreviada app.yaml ajustada para Python 3 precisa ser encurtada para ficar assim:

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

Resumindo as diferenças em app.yaml ao fazer a portabilidade para Python 3:

  • Excluir as configurações de threadsafe e api_version
  • Excluir seção libraries
  • Exclua a seção handlers (ou apenas os gerenciadores script, se o app exibir arquivos estáticos)

Substituir os valores

Os valores nas novas seções do Memorystore e do conector de VPC são apenas marcadores de posição. Substitua esses valores em letras maiúsculas (YOUR_REDIS_HOST, YOUR_REDIS_PORT, PROJECT_ID, REGION, CONNECTOR_NAME) pelos valores salvos de quando você criou esses recursos anteriormente. Com relação à sua instância do Memorystore, use HOST (não RESERVED_IP) e PORT. Esta é uma maneira rápida de linha de comando receber o HOST e o PORT, supondo que o nome de uma instância de demo-ms e REGION seja us-central1:

$ gcloud redis instances describe demo-ms --region us-central1 \
    --format "value(host,port)"
10.251.161.51   6379

Se o endereço IP da instância do Redis do nosso exemplo era 10.10.10.10 usando a porta 6379 no projeto my-project, localizado na região us-central1 com o nome de conector de VPC demo-vpc, essas seções em app.yaml vão ficar assim:

env_variables:
    REDIS_HOST: '10.10.10.10'
    REDIS_PORT: '6379'

vpc_access_connector:
    name: projects/my-project/locations/us-central1/connectors/demo-vpc

Criar ou atualizar appengine_config.py

Adicionar suporte a bibliotecas integradas de terceiros

Assim como fizemos com o app.yaml anteriormente, adicione o uso das bibliotecas grpcio e setuptools. Modifique appengine_config.py para oferecer suporte a bibliotecas integradas de terceiros. Isso parece familiar porque também era necessário no Módulo 2 ao migrar do ndb do App Engine para o Cloud NBS. A mudança exata necessária é adicionar a pasta lib ao conjunto de trabalho setuptools.pkg_resources:

4140b3800694f77e.png

*Diferenças do Python 3

Esta seção é opcional e somente se você estiver migrando para Python 3. Uma das mudanças bem-vindas da segunda geração do App Engine é que a cópia (às vezes chamada de "fornecimento") de pacotes (não integrados) de terceiros e a referência a pacotes de terceiros integrados no app.yaml não são mais necessárias, o que significa que é possível excluir todo o arquivo appengine_config.py.

6. Atualizar arquivos do aplicativo

Como há apenas um arquivo de aplicativo, main.py, todas as mudanças feitas na seção afetam apenas esse arquivo. Fornecemos uma representação pictórica das mudanças que serão feitas para migrar esse aplicativo para o Cloud Memorystore. Eles são apenas ilustrativos e não precisam ser analisados com cuidado. Todo o trabalho está nas mudanças que fazemos no código.

5d043768ba7be742.png

Vamos abordar cada seção, começando pelo topo.

Atualizar importações

A seção de importação em main.py para o Módulo 12 usa o Cloud NBS e o Cloud Tasks. estas são as importações:

ANTES:

from flask import Flask, render_template, request
from google.appengine.api import memcache
from google.appengine.ext import ndb

Mudar para o Memorystore requer a leitura de variáveis de ambiente, o que significa que precisamos do módulo Python os, bem como do redis, o cliente Python Redis. Como o Redis não pode armazenar objetos Python em cache, organize a lista de visitas mais recentes usando pickle. Portanto, importe-a também. Um benefício do Memcache é que a serialização de objetos acontece automaticamente, enquanto o Memorystore é um pouco mais "aprenda a fazer". Por fim, faça upgrade do App Engine ndb para o Cloud Node. Para isso, substitua google.appengine.ext.ndb por google.cloud.ndb. Depois dessas alterações, as importações vão ficar assim:

DEPOIS:

import os
import pickle
from flask import Flask, render_template, request
from google.cloud import ndb
import redis

Atualizar inicialização

A inicialização do Módulo 12 consiste em instanciar o objeto de aplicativo Flask app e definir uma constante para armazenamento em cache de uma hora:

ANTES:

app = Flask(__name__)
HOUR = 3600

O uso das APIs do Cloud requer um cliente. Portanto, instancie um cliente do Cloud NFS logo após o Flask. Em seguida, acesse o endereço IP e o número da porta da instância do Memorystore das variáveis de ambiente definidas em app.yaml. Com essas informações, instancie um cliente Redis. Seu código ficará assim depois dessas atualizações:

DEPOIS:

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)

*Migração para Python 3

Esta seção é opcional e se você estiver começando pela versão Python 3 do aplicativo Módulo 12. Nesse caso, há várias mudanças necessárias relacionadas às importações e à inicialização.

Primeiro, como o Memcache é um serviço empacotado do App Engine, o uso dele em um aplicativo Python 3 exige o SDK do App Engine, especificamente encapsulando o aplicativo WSGI (bem como outra configuração necessária):

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

Como estamos migrando para o Cloud Memorystore, e não um serviço incluído no App Engine, como o Memcache, o uso do SDK precisa ser removido. Isso é simples, já que você exclui a linha inteira que importa memcache e wrap_wsgi_app. Exclua também a linha que chama wrap_wsgi_app(). Essas atualizações deixam essa parte do aplicativo (na verdade, o aplicativo inteiro) idêntica à versão do Python 2.

DEPOIS:

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 fim, remova o uso do SDK de app.yaml (exclua a linha: app_engine_apis: true) e requirements.txt (exclua a linha: appengine-python-standard).

Migrar para o Cloud Memorystore (e Cloud NBS)

O modelo de dados do Cloud NBS precisa ser compatível com os ndb do App Engine, o que significa que a definição dos objetos Visit permanece a mesma. Imitando a migração do Módulo 2 para o Cloud NFS, todas as chamadas do Datastore em store_visit() e fetch_visits() são aumentadas e incorporadas em um novo bloco with, já que o uso do gerenciador de contexto do Cloud NBS é necessário. Estas são as chamadas antes dessa mudança:

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)

Adicione um bloco with ds_client.context() às duas funções e coloque as chamadas do Datastore dentro delas (e com recuo). Nesse caso, não é necessário fazer mudanças nas chamadas:

DEPOIS:

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 seguir, vamos analisar as alterações do armazenamento em cache. Esta é a função main() do 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)

O Redis tem o comando "get" e "definir" chamadas, assim como o Memcache. Tudo o que fazemos é trocar as respectivas bibliotecas de clientes, certo? Quase. Como mencionado anteriormente, não é possível armazenar em cache uma lista Python com o Redis, porque ela precisa ser serializada primeiro, algo que o Memcache cuida automaticamente. Portanto, na chamada set(), "pickle" as visitas em uma string com pickle.dumps(). Da mesma forma, ao recuperar visitas do cache, você precisa descartá-las com pickle.loads() logo após get(). Este é o gerenciador principal depois de implementar essas mudanças:

DEPOIS:

@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)

Isso conclui as alterações necessárias no main.py, convertendo o uso do Memcache do app de amostra para o Cloud Memorystore. E o modelo HTML e a portabilidade para Python 3?

Atualizar o arquivo do modelo HTML e a porta para o Python 3?

Surpresa! Não há nada a fazer aqui, já que o aplicativo foi projetado para ser executado em Python 2 e 3 sem nenhuma mudança de código nem bibliotecas de compatibilidade. Você vai encontrar main.py. idêntico em todo o mod13a (2.x) e mod13b (3.x) "FINISH" do Google Cloud. O mesmo vale para requirements.txt , exceto pelas diferenças nos números de versão (se usado). Como a interface do usuário permanece inalterada, não há atualizações para templates/index.html.

Tudo o que é necessário para executar esse app no App Engine para Python 3 foi concluído anteriormente na configuração: diretivas desnecessárias foram removidas do app.yaml e as pastas appengine_config.py e lib foram excluídas porque não são usadas no Python 3.

7. Resumo/limpeza

Esta seção encerra este codelab implantando o app, verificando se ele funciona conforme o esperado e em qualquer saída refletida. Após a validação do app, faça uma limpeza e considere as próximas etapas.

Implante e verifique o aplicativo

A última verificação é sempre implantar o app de exemplo. Desenvolvedores em Python 2: excluam e reinstalem lib com os comandos abaixo. Se você tiver o Python 2 e o 3 instalados no sistema, talvez seja necessário executar explicitamente pip2.

rm -rf ./lib
pip install -t lib -r requirements.txt

Os desenvolvedores de Python 2 e 3 agora devem implantar os aplicativos com:

gcloud app deploy

Como você apenas reconfigurou as coisas em segundo plano para um serviço de armazenamento em cache completamente diferente, o aplicativo em si deve operar de forma idêntica ao aplicativo do Módulo 12:

App visitme do módulo 7

Esta etapa conclui o codelab. Convidamos você a comparar seu app de exemplo atualizado com uma das pastas do Módulo 13, mod13a (Python 2) ou mod13b (Python 3).

Limpar

Geral

Se você já tiver terminado por enquanto, recomendamos que desative seu aplicativo do App Engine para evitar cobranças. No entanto, se você quiser fazer mais testes, saiba que a plataforma do App Engine tem uma cota sem custo financeiro e, desde que você não exceda esse nível de uso, não haverá cobranças. Isso é para computação, mas também pode haver cobranças por serviços relevantes do App Engine. Portanto, consulte a página de preços para mais informações. Se essa migração envolver outros serviços do Cloud, eles serão faturados separadamente. Em ambos os casos, se aplicável, consulte a seção "Específico para este codelab". seção abaixo.

Para divulgação completa, a implantação em uma plataforma de computação sem servidor do Google Cloud, como o App Engine, incorre em menores custos de criação e armazenamento. O Cloud Build tem a própria cota sem custo financeiro, assim como o Cloud Storage. O armazenamento da imagem consome parte da cota. No entanto, talvez você more em uma região que não tenha esse nível sem custo financeiro, portanto, esteja ciente do uso do armazenamento para minimizar os possíveis custos. "Pastas" específicas do Cloud Storage que você deve analisar incluem:

  • 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
  • Os links de armazenamento acima dependem do PROJECT_ID e da *LOC*ação, por exemplo, "us" caso seu app esteja hospedado nos EUA.

Por outro lado, se você não for continuar com este aplicativo ou outros codelabs de migração relacionados e quiser excluir tudo completamente, encerre seu projeto.

Específicos deste codelab

Os serviços listados abaixo são exclusivos deste codelab. Consulte a documentação de cada produto para mais informações:

Este tutorial envolveu o uso de quatro produtos do Cloud:

  • App Engine
  • Cloud Datastore
  • Cloud Memorystore
  • Cloud VPC

Confira abaixo as instruções para liberar esses recursos e evitar/minimizar cobranças de faturamento.

Encerrar a instância do Memorystore e o conector VPC

Esses são os produtos sem um nível sem custo financeiro. Você está recebendo o faturamento agora. Se você não encerrar seu projeto do Cloud (consulte a próxima seção), será necessário excluir a instância do Memorystore e o conector de VPC para interromper o faturamento. Assim como quando você criou esses recursos, também é possível liberá-los no console do Cloud ou na linha de comando.

No console do Cloud

Para excluir a instância do Memorystore, volte ao painel do Memorystore e clique no ID da instância:

2b09baf1aa2e0a25.png

Na página de detalhes da instância, clique em "Excluir" e confirme:

f9d9eb1c1d4c6107.png

Para excluir o conector VPC, acesse o painel dele, marque a caixa de seleção ao lado do conector que você quer excluir e clique em "Excluir". e confirme:

ca5fbd9f4c7c9b60.png

Na linha de comando

O par de comandos gcloud a seguir exclui a instância do Memorystore e o conector VPC, respectivamente:

  • gcloud redis instances delete INSTANCE --region REGION
  • gcloud compute networks vpc-access connectors delete CONNECTOR --region REGION

Se você não tiver definido o ID do projeto com gcloud config set project, será necessário fornecer --project PROJECT_ID. Se o nome da instância do Memorystore for demo-ms e do conector da VPC forem demo-vpc, e ambos estiverem na região us-central1, emita os seguintes pares de comandos e confirme:

$ 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 solicitação leva alguns minutos para ser executada. Essas etapas são opcionais se você optar por encerrar todo o seu projeto do Cloud, conforme descrito anteriormente. No entanto, você ainda vai receber cobranças até que o processo de encerramento seja concluído.

Próximas etapas

Além deste tutorial, outros módulos de migração que se concentram em abandonar os serviços em pacote legados a considerar incluem:

  • Módulo 2: migrar do App Engine ndb para o Cloud NBS
  • Módulos 7 a 9: migrar de tarefas push da fila de tarefas do App Engine para o Cloud Tasks
  • Módulos 12 a 13: migrar do Memcache do App Engine para o Cloud Memorystore
  • Módulos 15 a 16: migrar do App Engine Blobstore para o Cloud Storage
  • Módulos 18 a 19: migrar da fila de tarefas do App Engine (tarefas pull) para o Cloud Pub/Sub

O App Engine não é mais a única plataforma sem servidor do Google Cloud. Se você tem um aplicativo pequeno do App Engine ou com funcionalidade limitada e quer transformá-lo em um microsserviço independente ou quer dividir um aplicativo monolítico em vários componentes reutilizáveis, estes são bons motivos para migrar para o Cloud Functions. Se a conteinerização se tornou parte do fluxo de trabalho de desenvolvimento de aplicativos, principalmente se consistir em um pipeline de CI/CD (integração/entrega contínua ou implantação), considere migrar para o Cloud Run. Esses cenários são abordados nos seguintes módulos:

  • Migrar do App Engine para o Cloud Functions: consulte o Módulo 11
  • Migrar do App Engine para o Cloud Run: consulte o Módulo 4 para conteinerizar seu app com o Docker ou o Módulo 5 para fazer isso sem contêineres, conhecimento do Docker ou Dockerfiles

A mudança para outra plataforma sem servidor é opcional. Recomendamos considerar as melhores opções para seus apps e casos de uso antes de fazer qualquer mudança.

Seja qual for o módulo de migração que você considerar a seguir, todo o conteúdo da estação de migração sem servidor (codelabs, vídeos, código-fonte [quando disponível]) pode ser acessado no repositório de código aberto. O README do repositório também fornece orientações sobre quais migrações considerar e qualquer "ordem" relevante. de módulos de migração.

8. Outros recursos

Abaixo estão listados recursos adicionais para desenvolvedores que querem explorar melhor esse Módulo de migração ou o relacionado, assim como produtos relacionados. Isso inclui locais para fornecer feedback sobre esse conteúdo, links para o código e várias documentações que podem ser úteis.

Problemas/feedback sobre codelabs

Se você encontrar problemas com este codelab, pesquise seu problema antes de preenchê-lo. Links para pesquisar e criar novos problemas:

Recursos de migração

Os links para as pastas do repositório do Módulo 12 (INÍCIO) e do Módulo 13 (FINISH) podem ser encontrados na tabela abaixo. Eles também podem ser acessados no repositório de todas as migrações de codelab do App Engine. Você pode clonar ou fazer o download de um arquivo ZIP.

Codelab

Python 2

Python 3

Módulo 12

código

código

Módulo 13 (este codelab)

código

código

Referências on-line

Veja abaixo recursos on-line que podem ser relevantes para este tutorial:

App Engine

O App Engine App Engine e o Cloud Node

Memcache do App Engine e Cloud Memorystore

Cloud VPC

Outras informações sobre a nuvem

Licença

Este conteúdo está sob a licença Atribuição 2.0 Genérica da Creative Commons.