我们在单个 AppEngine 应用 (Python) 中从不同模块 (也称为“服务”) 执行 memcache 查找时偶尔会遇到不一致的情况。情况如下:
模块“portal”创建并随后增加某个 memcache 键的整数值:
@ndb.tasklet def increment_total_async(meter): total = yield memcache.Client().incr_async( key="some-key", namespace=TOTALS_NAMESPACE, delta=meter.quantity) if total is not None: raise ndb.Return(total) raise ndb.Return(None)
模块“dashboard”稍后使用相同的键和命名空间查找当前值:
@ndb.transactional_tasklet def get_total_async(subscription, metric): total = memcache.get( key="some-key", namespace=TOTALS_NAMESPACE) if total is not None: raise ndb.Return(total) raise ndb.Return(None)
有趣的是,当从“仪表板”模块调用时,get_total_async 有时(很少)返回整数值 0(而不是 None),而当从“门户”模块调用时,它返回(正确)值>0。
这有点令人惊讶,让我们相信 memcache 服务中可能存在竞争条件 - 可能只有当从不同的模块(现在被 Google 称为“服务”)查找相同的密钥时才会出现。
有人遇到过类似现象吗?这是一个“Heisenbug”,即难以重现。