Google app engine Google应用程序引擎碎片计数器不工作,正在获取dup编号

Google app engine Google应用程序引擎碎片计数器不工作,正在获取dup编号,google-app-engine,Google App Engine,我正在使用Google App Engine编写一个bug数据库,但在获取bug的唯一编号时遇到了问题。每个bug都需要一个唯一的编号,这样用户就可以很容易地引用它们,并且编号应该尽可能简单和小。“嘿,我修复了bug 27”或“我重新打开了bug 1867”。Bug数量也应该增加,以便用户大致了解哪个Bug之后出现了哪些Bug 应用程序引擎没有像SQL那样的真正计数器,所以我实现了下面的函数,这基本上是Google推荐的代码,但并不总是有效 我偶尔会看到重复的错误编号。目前,我是唯一一个使用bu

我正在使用Google App Engine编写一个bug数据库,但在获取bug的唯一编号时遇到了问题。每个bug都需要一个唯一的编号,这样用户就可以很容易地引用它们,并且编号应该尽可能简单和小。“嘿,我修复了bug 27”或“我重新打开了bug 1867”。Bug数量也应该增加,以便用户大致了解哪个Bug之后出现了哪些Bug

应用程序引擎没有像SQL那样的真正计数器,所以我实现了下面的函数,这基本上是Google推荐的代码,但并不总是有效

我偶尔会看到重复的错误编号。目前,我是唯一一个使用bug数据库的人(从图标上说,这个bug在我的bug数据库中),我输入bug的速度不会比每5秒或10秒输入一个更快(如果我输入得快的话)。尽管最终可能会有多个用户同时输入bug

class SimpleCounterShard(db.Model):
    count = db.IntegerProperty(required=True, default=0)

def getNewID():
    def txn():
        index = random.randint(0, NUM_SHARDS - 1)
        shard_name = "shard" + str(index)
        counter = SimpleCounterShard.get_by_key_name(shard_name)
        if counter is None:
            counter = SimpleCounterShard(key_name=shard_name)
        counter.count += 1
        counter.put()
    db.run_in_transaction(txn)

    total = 0
    for counter in SimpleCounterShard.all():
        total += counter.count

    return total

我做错了什么(或不理解)?或者,有没有更好的方法来获取唯一的数字,而不是像密钥或ID在某些情况下在生产服务器上那样随机出现。

您的代码不是真正的线程安全代码。是的,您使用事务增加计数器,但不使用它读取计数器。还有一些您在该事务中没有锁定的碎片(因为它们位于不同的实体组中)。您可以想象两个请求增加计数器,然后在事务之外读取值(获得相同的值)。 您基本上需要做事务中的所有事情,并且只需要一个碎片。这意味着阻止对新id的多个调用(序列化它们)。我建议对每个项目/标记/上下文/任何内容使用不同的计数器,以更好地扩展写入

阅读更多关于交易的信息


老实说,如果我是你,我只会使用自动生成的模型ID。

你的代码不是真正的线程安全。是的,您使用事务增加计数器,但不使用它读取计数器。还有一些您在该事务中没有锁定的碎片(因为它们位于不同的实体组中)。您可以想象两个请求增加计数器,然后在事务之外读取值(获得相同的值)。 您基本上需要做事务中的所有事情,并且只需要一个碎片。这意味着阻止对新id的多个调用(序列化它们)。我建议对每个项目/标记/上下文/任何内容使用不同的计数器,以更好地扩展写入

阅读更多关于交易的信息


老实说,如果我是你,我只会使用自动生成的模型ID。

切分计数器将有与内置自动生成ID完全相同的问题(如果你可以这么说的话):它们不保证单调性。分片计数器的设计目的是让你可以数数东西,而不是给东西分配数字;因此,您无法事务性地获得所有碎片的总和,并且您的结果是错误的

你真的应该只使用内置的自动编号;我怀疑用户是否会认真关注彼此之间bug数量的大小,如果您希望它们扩展到高写入率,那么您可以提出的大多数解决方案都会有类似的问题


如果绝对必须有序列号,则可以使用单个计数器实体,并允许每秒1-10次的最大插入速率,或者启动“计数器”后端,从数据存储中批量分配ID,并根据前端的RPC请求分发ID。如果后者听起来很熟悉,那是因为自动生成的ID就是这样做的,只在多台机器上进行切分。

切分计数器将遇到与内置自动生成ID完全相同的问题(如果可以这么说的话):它们不保证单调性。分片计数器的设计目的是让你可以数数东西,而不是给东西分配数字;因此,您无法事务性地获得所有碎片的总和,并且您的结果是错误的

你真的应该只使用内置的自动编号;我怀疑用户是否会认真关注彼此之间bug数量的大小,如果您希望它们扩展到高写入率,那么您可以提出的大多数解决方案都会有类似的问题


如果绝对必须有序列号,则可以使用单个计数器实体,并允许每秒1-10次的最大插入速率,或者启动“计数器”后端,从数据存储中批量分配ID,并根据前端的RPC请求分发ID。如果后者听起来很熟悉,那是因为自动生成的ID就是这样做的,只在多台机器上进行切分。

模型ID的问题是它们经常跳转。我会找几个14,15,然后一个是9007。对于跟踪用户面临的bug数量,这可能会产生很大的误导。模型ID的问题是它们经常出现反弹。我会找几个14,15,然后一个是9007。对于跟踪用户面临的错误编号,这可能会产生误导。感谢您的回复。至于bug数量,在一个有成千上万个bug的大型项目中可能并不重要,但对于一个有几百个bug的小型独立项目来说,当最后一个bug是71时,将10201视为bug数量确实会引起一些人的恐慌。我也是强迫症患者,当涉及到这样的事情时。:-)谢谢你的回复。至于bug数量,在一个有成千上万个bug的大型项目中可能并不重要,但对于一个有几百个bug的小型独立项目来说,当最后一个bug是71时,将10201视为bug数量确实会引起一些人的恐慌。我也是强迫症患者,当涉及到这样的事情时。:-)