Como migrar do Memcache para o Memorystore

Os aplicativos da Web escalonáveis de alto desempenho do Python geralmente usam um cache de dados na memória distribuído em vez de um armazenamento permanente robusto para algumas tarefas.

A solução do App Engine para isso é o Memcache, um armazenamento de dados distribuído na memória que é usado como um cache para tarefas específicas.

Ao migrar serviços agrupados legados, a substituição recomendada para o Memcache do App Engine é o Memorystore, um serviço de armazenamento em cache totalmente gerenciado e baseado em nuvem que é compatível com mecanismos de armazenamento em cache de código aberto, como Redis e Memcached. Este guia abrange o uso do Memorystore para Redis, que pode criar caches de aplicativos que fornecem acesso a dados em menos de um milissegundo.

Se o aplicativo Python usa o Memcache apenas para reduzir a latência de solicitações de ndb ou do Cloud NDB, é possível usar o suporte integrado do Cloud NBD para Redis em vez do Memcache ou do Memorystore para Redis.

Antes de começar, verifique se o aplicativo permanecerá dentro das cotas do Memorystore para Redis.

Quando usar um cache de memória para aplicativos Python

Nos aplicativos Python, os dados de sessão, as preferências do usuário e outros dados retornados por consultas de páginas da Web são bons candidatos para o armazenamento em cache. Em geral, se uma consulta executada com frequência retorna um conjunto de resultados que não precisam aparecer no aplicativo imediatamente, é possível armazená-los em cache. As solicitações posteriores poderão verificar o cache e consultar o banco de dados apenas se os resultados estiverem ausentes ou expirados.

Se você armazenar um valor apenas no Memorystore sem fazer backup no armazenamento permanente, verifique se o aplicativo se comporta de maneira aceitável quando o valor expirar e for removido do cache. Por exemplo, se a ausência repentina dos dados da sessão de um usuário fizer a sessão funcionar incorretamente, esses dados provavelmente serão armazenados no banco de dados, além do Memorystore.

Antes de começar

Se você ainda não tiver feito isso, configure o ambiente de desenvolvimento do Python para usar uma versão do Python compatível com o Google Cloud e instale ferramentas de teste para criar Python isolado.

Noções básicas sobre as permissões do Memorystore

Toda interação com um serviço do Google Cloud precisa ser autorizada. Por exemplo, para interagir com um banco de dados do Redis hospedado pelo Memorystore, seu aplicativo precisa fornecer as credenciais de uma conta que está autorizada a acessar o Memorystore.

Por padrão, o aplicativo fornece as credenciais da conta de serviço padrão do App Engine, que está autorizada a acessar bancos de dados no mesmo projeto que o aplicativo.

Se alguma das seguintes condições for verdadeira, você precisará usar uma técnica de autenticação alternativa que forneça credenciais explicitamente:

  • Seu aplicativo e o banco de dados do Memorystore estão em projetos diferentes do Google Cloud.

  • Você alterou os papéis atribuídos à conta de serviço padrão do App Engine.

Para saber mais sobre técnicas de autenticação alternativas, veja Como configurar a autenticação para aplicativos de produção de servidor para servidor.

Visão geral do processo de migração

Para usar o Memorystore em vez do Memcache no app Python, faça o seguinte:

  1. Configure o Memorystore para Redis, que exige que você crie uma instância do Redis no Memorystore e um acesso VPC sem servidor que o aplicativo usará para se comunicar com a instância do Redis. A ordem de criação dessas duas entidades independentes não é estrita e pode ser configurada em qualquer ordem. As instruções neste guia mostram primeiro a configuração do acesso VPC sem servidor.

  2. Instale uma biblioteca de cliente para Redis e use os comandos do Redis a fim de armazenar dados em cache.

    O Memorystore para Redis é compatível com qualquer biblioteca de cliente para Redis.

    Este guia descreve o uso da biblioteca de cliente redis-py para enviar comandos do Redis por meio do aplicativo.

  3. Teste as atualizações.

  4. Implante o aplicativo no App Engine.

Como configurar o Memorystore para Redis

Para configurar o Memorystore para Redis:

  1. Conecte o App Engine a uma rede VPC. Seu aplicativo só pode se comunicar com o Memorystore por meio de um conector VPC.

    Não se esqueça de adicionar as informações de conexão de VPC ao arquivo app.yaml, conforme descrito em Como configurar seu aplicativo para usar um conector.

  2. Anote o endereço IP e o número da porta da instância do Redis criada. Você usará essas informações ao criar um cliente Redis no seu código.

  3. Crie uma instância do Redis no Memorystore.

    Quando for solicitado que você selecione uma região para a instância do Redis, escolha a mesma região em que o aplicativo do App Engine está.

Como instalar dependências

Para usar a biblioteca de cliente redis-py, faça isto:

  1. Atualize o arquivo app.yaml. Siga as instruções para sua versão do Python:

    Python 2

    Para aplicativos Python 2, adicione as versões mais recentes das bibliotecas grpcio e setuptools.

    A seguir, um exemplo de arquivo app.yaml:

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

    Python 3

    Para aplicativos Python 3, especifique o elemento runtime no arquivo app.yaml com uma versão compatível do Python 3. Por exemplo:

    runtime: python310 # or another support version
    

    O ambiente de execução do Python 3 instala bibliotecas automaticamente. Portanto, não é necessário especificar bibliotecas integradas do ambiente de execução anterior do Python 2. Se o aplicativo Python 3 estiver usando outros serviços legados em pacote durante a migração, será possível especificar as bibliotecas integradas necessárias. Caso contrário, exclua as linhas desnecessárias do arquivo app.yaml.

  2. Atualize o arquivo requirements.txt. Siga as instruções para sua versão do Python:

    Python 2

    Adicione as bibliotecas de cliente do Cloud relativas ao Memorystore para Redis à sua lista de dependências no arquivo requirements.txt.

    redis
    

    Execute pip install -t lib -r requirements.txt para atualizar a lista de bibliotecas disponíveis para o app.

    Python 3

    Adicione as bibliotecas de cliente do Cloud relativas ao Memorystore para Redis à sua lista de dependências no arquivo requirements.txt.

    redis
    

    O App Engine instala automaticamente essas dependências durante a implantação do app no ambiente de execução do Python 3. Portanto, exclua a pasta lib, se houver uma.

  3. No caso de um app Python 2, se ele usar bibliotecas integradas ou copiadas especificadas no diretório lib, especifique esses caminhos no arquivo appengine_config.py, localizado na mesma pasta do arquivo 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)
    

Como criar um cliente Redis

Para interagir com um banco de dados Redis, seu código precisa criar um cliente Redis para gerenciar a conexão com o banco de dados Redis. As seções a seguir descrevem a criação de um cliente Redis usando a biblioteca de cliente redis-py.

Como especificar variáveis de ambiente

A biblioteca de cliente Redis usa duas variáveis de ambiente para montar o URL do banco de dados do redis-py:

  • Uma variável para identificar o endereço IP do banco de dados do Redis criado no Memorystore.
  • Uma variável para identificar o número da porta do banco de dados do Redis criado no Memorystore.

Recomendamos que você defina essas variáveis no arquivo app.yaml do aplicativo em vez de defini-las diretamente no código. Isso facilita a execução do aplicativo em diferentes ambientes, como um ambiente local e o App Engine.

Por exemplo, adicione as seguintes linhas ao seu arquivo app.yaml:

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

Como importar a redis-py e criar o cliente

Depois de definir as variáveis de ambiente REDISHOST e REDISPORT, use as seguintes linhas para importar a biblioteca redis-py e criar um 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)

Se você usou uma versão mais antiga de redis-py em outros aplicativos, talvez tenha usado a classe StrictClient em vez de Client. No entanto, redis-py agora recomenda Client em vez de StrictClient.

Como usar comandos do Redis para armazenar e recuperar dados no cache

Embora o banco de dados do Memorystore para Redis seja compatível com a maioria dos comandos do Redis, você só precisa usar alguns deles para armazenar e recuperar dados do cache. A tabela a seguir sugere comandos do Redis que você pode usar para armazenar dados em cache. Para saber como chamar esses comandos a partir do aplicativo, veja a documentação da sua biblioteca de cliente.

Para apps Python 2, embora o Memcache forneça alternativas assíncronas para muitos dos comandos, a biblioteca de cliente redis-py nem sempre fornece métodos assíncronos equivalentes. Se você precisa que todas as interações com o cache sejam assíncronas, há outras bibliotecas de cliente do Redis para Python disponíveis.

Tarefa Comando do Redis
Criar uma entrada no cache de dados e
definir um prazo de validade para a entrada
SETNX
MSETNX
Recuperar dados do cache GET
MGET
Substituir valores de cache existentes SET
MSET
Aumentar ou diminuir valores de cache numéricos INCR
INCRBY
DECR
DECRBY
Excluir entradas do cache DEL
UNLINK
Fornecer suporte a interações simultâneas com o cache (comparação e configuração) Veja detalhes sobre as transações do Redis. A biblioteca de cliente "redis-py" exige que todas as transações ocorram em um pipeline.

Como testar suas atualizações

Ao testar seu aplicativo localmente, considere a execução de uma instância local do Redis para evitar a interação com dados de produção (o Memorystore não fornece um emulador). Para instalar e executar o Redis localmente, siga as instruções na documentação do Redis. Ainda não é possível executar o Redis localmente no Windows.

Para mais informações sobre como testar aplicativos Python, consulte Como usar o servidor de desenvolvimento local.

Como implantar o app

Quando seu aplicativo estiver em execução no servidor de desenvolvimento local sem erros:

  1. Teste o aplicativo no App Engine.

  2. Se o aplicativo for executado sem erros, use a divisão de tráfego para aumentar gradualmente o tráfego para o aplicativo atualizado. Monitore de perto o aplicativo em busca de problemas no banco de dados antes de direcionar mais tráfego para o aplicativo atualizado.

A seguir