Python 分片计数器RPC和计算的成本增加

Python 分片计数器RPC和计算的成本增加,python,google-app-engine,google-cloud-datastore,app-engine-ndb,sharding,Python,Google App Engine,Google Cloud Datastore,App Engine Ndb,Sharding,我正在为我的谷歌应用程序引擎切分计数器实现做一些诊断,我不确定额外的RPC是从哪里来的 获取20个计数器的非缓存计数时,具有20个碎片的开箱即用版本在Appstats中提供以下信息: RPCs memcache.get 100 memcache.set 80 memcache.del 0 datastore.get 60 datastore_commit

我正在为我的谷歌应用程序引擎切分计数器实现做一些诊断,我不确定额外的RPC是从哪里来的

获取20个计数器的非缓存计数时,具有20个碎片的开箱即用版本在Appstats中提供以下信息:

RPCs
memcache.get                100  
memcache.set                80  
memcache.del                0  
datastore.get               60  
datastore_commit            0  
datastore_put               0  
datastore_begin_transaction 0

Billed Ops  
datastore_read              420  
datastore_write             0  

Cost                        29,400
以下是计数器代码,以供参考:

class GeneralCounterShard(ndb.Model):
    """Shards for each named counter."""
    count = ndb.IntegerProperty(default=0)


def get_count(name):
    """Retrieve the value for a given sharded counter.
    Args:
        name: The name of the counter.
    Returns:
        Integer; the cumulative count of all sharded counters for the given
            counter name.
    """
    total = memcache.get(name)
    if total is None:
        total = 0
        all_keys = GeneralCounterShardConfig.all_keys(name)
        for counter in ndb.get_multi(all_keys):
            if counter is not None:
                total += counter.count
        memcache.add(name, total, 60)
    return total
当我更改切分计数器代码以使get_count成为GeneralCounterShard类的“classmethod”时,RPC发生了巨大的变化:

RPCs
memcache.get                100  
memcache.set                80  
memcache.del                20  
datastore.get               80  
datastore_commit            20  
datastore_put               20  
datastore_begin_transaction 20

Billed Ops
datastore_read              440  
datastore_write             60   

Cost                        36,800
以下是更改内容供参考:

class GeneralShardedCounter(ndb.Model):

    count = ndb.IntegerProperty(default=0)

    @classmethod
    def get_count(name):

        total = memcache.get(name)
        if total is None:
            total = 0
            all_keys = GeneralShardedCounterConfig.all_keys(name)
            for counter in ndb.get_multi(all_keys):
                if counter is not None:
                    total += counter.count
            memcache.add(name, total, 60)
        return total
综上所述,两者的区别在于:

RPCs
memcache.get                +0  
memcache.set                +0  
memcache.del                +20  
datastore.get               +20  
datastore_commit            +20  
datastore_put               +20  
datastore_begin_transaction +20 

Billed Ops
datastore_read              +20  
datastore_write             +60  

Cost                        +7,400 

仅仅通过将一个方法作为ndb模型的classmethod,什么会导致RPC和读写的跳跃?

我怀疑答案几乎肯定在于ndb的内置实体缓存,所以我想你会看到,比如,
+n
memcache.del
调用带有
n
碎片的计数器。我不明白的是
@classmethod
是如何改变这一点的(我不是python内部专家)。您能在调用
get\u count()
的地方张贴行吗?类方法将该类名作为第一个参数。我不清楚这是否与你的柜台名称相同。你想改用静态方法吗?所以,它看起来像一个假阳性。我没有意识到数据存储为计数器配置创建了一个记录,但这就是其他20个put的来源。每个柜台一个。我第一次运行这个程序时,数据存储是空的。