You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AppEngine py2.7应用迁py3时memcache替换为Redis相关疑问

解答

1. ndb Redis全局缓存配置规则

你不需要给每一个查询都套示例中的with上下文块,全局配置一次即可生效:

  • 新版兼容py2.7/py3的google-cloud-ndb库把缓存层做了抽象,Redis全局缓存的作用和旧版ndb内置的memcache完全一致,配置完成后所有ndb的get、put、查询操作都会自动走缓存、自动失效,和你之前用memcache时的ndb行为没有任何区别。
  • 示例中的with块只是演示单次上下文绑定的用法,实际生产可以在服务初始化入口(py2.7可以写在appengine_config.py中,py3可以写在flask请求中间件里)统一绑定缓存上下文,不需要修改原有业务查询代码。
  • 缓存命中逻辑和旧版完全一致:单key查询的实体、普通查询结果都会自动存入Redis,有缓存时优先读缓存,写入实体时自动清理对应缓存。

2. 自定义业务缓存的迁移方案

你完全可以复用之前memcache的自定义缓存逻辑,包括缓存键规则、失效策略,只需要把memcache的API替换成Redis API即可:
你之前存用户游戏列表这类聚合数据的逻辑不需要改动,只需要解决ndb实体的序列化问题即可,示例如下:

import pickle
from redis import Redis

# 初始化Redis客户端,全局复用即可
redis_client = Redis(host="你的Redis实例内网地址", port=6379, db=0)

# 读缓存逻辑,和之前的memcache写法几乎一致
cache_key = userskey.urlsafe() + "_gamesList"
cached_data = redis_client.get(cache_key)
if cached_data:
    # 反序列化得到ndb实体列表
    games_list = pickle.loads(cached_data)
else:
    # 查库重建缓存
    games_list = Game.query(Game.user_key == userskey).fetch()
    # 序列化后存入Redis,过期时间和之前保持一致,指定protocol=2保证py2.7和py3序列化兼容
    redis_client.setex(cache_key, 3600, pickle.dumps(games_list, protocol=2))

# 数据变更时失效缓存,和之前逻辑一致
redis_client.delete(cache_key)

单独缓存用户账号模型的逻辑和上面完全相同,用用户key作为缓存键即可。

3. 新旧服务并行的注意事项

只要两边保持两个规则统一,就可以实现缓存完全共用,支持流量拆分、beta用户测试:

  • ndb全局缓存的key前缀保持一致
  • 自定义缓存的键规则、pickle序列化协议(指定为2)保持一致

你原有的90%缓存命中率可以完全复刻到Redis上,不需要额外调整缓存策略。


内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 00:00:05