同一应用程序的不同 Google AppEngine 模块的 memcache 查找不一致

同一应用程序的不同 Google AppEngine 模块的 memcache 查找不一致

我们在单个 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”,即难以重现。

相关内容