将 Memcache 迁移到 Memorystore

Memcache 是捆绑在 Python 2 运行时环境中的分布式内存数据存储。许多 App Engine 应用将 Memcache 用作特定任务的缓存,而不是仅依赖于永久性存储空间。

Memorystore for Redis 提供完全托管式服务,该服务由 Redis 内存数据存储提供支持,以构建提供亚毫秒级数据访问的应用缓存。

如果您的 Python 2 应用使用 Memcache 仅减少 ndb 或 Cloud NDB 请求的延迟时间,则可以使用 Cloud NDB 对 Redis 的内置支持,而不是 Memcache Memorystore for Redis。

了解 Memorystore 权限

与 Google Cloud 服务之间进行的每一次交互操作都需要经过授权。例如,如需与 Memorystore 托管的 Redis 数据库进行交互,您的应用需要提供有权访问 Memorystore 的帐号的相应凭据。

默认情况下,您的应用会提供 App Engine 默认服务帐号的凭据,该帐号有权访问与您应用同属一个项目中的数据库。

如果满足以下任何条件,则您需要使用明确提供凭据的备用身份验证技术:

  • 您的应用和 Memorystore 数据库位于不同的 Google Cloud 项目中。

  • 您已更改分配给默认 App Engine 服务帐号的角色。

如需了解备用身份验证技术,请参阅为服务器到服务器的生产应用设置身份验证

迁移过程概览

如需迁移 Python 应用以使用 Memorystore 而不是 Memcache,请执行以下操作:

  1. 设置 Memorystore for Redis,此操作需要您在 Memorystore 上创建 Redis 实例并创建无服务器 VPC 访问通道,以供您的应用与 Redis 实例通信。 创建这两个独立实体的顺序并不严格,可以按任意顺序设置。本指南中的说明首先显示如何设置无服务器 VPC 访问通道。

  2. 安装适用于 Redis 的客户端库并使用 Redis 命令缓存数据。

    Memorystore for Redis 与适用于 Redis 的任何客户端库都兼容。本指南将介绍如何使用 redis-py 3.0 客户端库从您的应用中发送 Redis 命令。

  3. 测试您的更新

  4. 将应用部署到 App Engine

设置 Memorystore for Redis

如需设置 Memorystore for Redis,请执行以下操作:

  1. 将 App Engine 连接到 VPC 网络。您的应用只能通过 VPC 连接器与 Memorystore 通信。

    请务必按照将应用配置为使用连接器中的说明,将 VPC 连接信息添加到 app.yaml 文件中。

  2. 记下您创建的 Redis 实例的 IP 地址和端口号。您在自己的代码中创建 Redis 客户端时,将会用到这些信息。

  3. 在 Memorystore 中创建 Redis 实例

    当系统提示您为 Redis 实例选择地区时,请选择您的 App Engine 应用所在的地区

安装依赖项

如需使应用在 App Engine 中运行时能够使用 redis-py 客户端库,请执行以下操作:

  1. 将以下行添加到您应用的 requirements.txt 文件中:

     redis
    
  2. 如果您仍在 Python 2 运行时中运行应用:

    1. 使用带有 -t <directory> 标志的 pip(版本 6 或更高版本)将库安装到名为 lib 的本地文件夹中。例如:

      pip install -t lib <library_name> -r requirements.txt

    2. 确保应用的 appengine_config.py 文件指定 lib 目录。

    App Engine 将上传您在 appengine_config.py 文件中指定的目录中的所有库。如需了解详情,请参阅使用 Python 2 库

当您部署应用时,App Engine Python 3 运行时环境将自动上传应用的 requirements.txt 文件中的所有库。

对于本地开发,我们建议您在虚拟环境(如 Python 2 的 virtualenv 或 Python 3 的 venv)中安装依赖项。

创建 Redis 客户端

如需与 Redis 数据库进行交互,您的代码需要创建 Redis 客户端才能管理与 Redis 数据库的连接。以下部分介绍如何使用 redis-py 客户端库创建 Redis 客户端。

指定环境变量

redis-py 客户端库使用两个环境变量为您的 Redis 数据库组建网址:

  • 用于标识您在 Memorystore 中创建的 Redis 数据库的 IP 地址的变量。
  • 用于标识您在 Memorystore 中创建的 Redis 数据库的端口号的变量。

我们建议您在应用的 app.yaml 文件中定义这些变量,而不是直接在您的代码中定义这些变量。这样可以更轻松地在不同的环境(例如本地环境和 App Engine)中运行您的应用。

例如,请将下面几行代码添加到 app.yaml 文件中:

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

导入 redis-py 并创建客户端

定义 REDISHOSTREDISPORT 环境变量后,请使用以下行导入 redis-py 库并创建客户端:

  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)

如果您对其他应用使用了旧版 redis-py,则可能使用过 StrictClient 类,而不是 Client。但是,redis-py 现在建议您使用 Client,而不是 StrictClient

使用 Redis 命令在缓存中存储和检索数据

虽然 Memorystore Redis 数据库支持大多数 Redis 命令,但您只需使用几个命令即可在缓存中存储和检索数据。下表建议了一些可用于缓存数据的 Redis 命令。如需了解如何从您的应用调用这些命令,请参阅客户端库的文档。

请注意,尽管 Memcache 为其许多命令提供了异步替代方案,但 redis-py 客户端库并非总是提供等效的异步方法。如果您要求与缓存的所有交互都是异步的,则可以使用其他 Python 版 Redis 客户端库
任务 Redis 命令
在数据缓存中创建一个条目,
并为该条目设置到期时间
SETNX
MSETNX
从缓存中检索数据 GET
MGET
替换现有的缓存值 SET
MSET
递增或递减缓存数值 INCR
INCRBY
DECR
DECRBY
从缓存中删除条目 DEL
UNLINK
支持与缓存进行并发交互(比较和设置 请参阅有关 Redis 事务的详细信息。请注意,redis-py 客户端库要求所有事务都在流水线中进行。

测试更新

当您在本地测试应用时,请考虑运行 Redis 的本地实例以避免与生产数据交互(Memorystore 不提供模拟器)。如需在本地安装并运行 Redis,请按照 Redis 文档中的说明进行操作。请注意,目前无法在 Windows 上本地运行 Redis。

如需详细了解如何测试 Python 2 应用,请参阅使用本地开发服务器

部署应用

一旦您的应用能够在本地开发服务器上无错误地正常运行,请执行以下操作:

  1. 在 App Engine 上测试应用

  2. 如果应用无错误地正常运行,请使用流量拆分功能为更新后的应用缓慢增加流量。请先仔细监控应用是否存在任何数据库问题,然后再将更多流量路由到更新后的应用。