AppEngine实现强一致性

时间:2016-08-25 08:48:56

标签: python google-app-engine eventual-consistency

我正在努力实现强大的一致性。让我们调用我的模型PVPPlayer

class PVPPlayer(ndb.Model):
    points = ndb.IntegerProperty()

模型的每个键都是这样创建的:

pvp_player = PVPPlayer(key=ndb.Key(Profile, "test_id", PVPPlayer, "test_id"))

其中Profile是父模型:

class Profile(ndb.Model):
    def build_key(cls, some_id):
        return ndb.Key(cls, some_id)

我有2个REST api url:

1) update_points
2) get_points

在1)我做:

# I use transaction because I have to update all the models in single batch 
@ndb.transactional(xg=True, retries=3)
def some_func(points):
    pvp_player = ndb.Key(Profile, "test_id", PVPPlayer, "test_id").get()
    pvp_player.points += points 
    pvp_player.put()
    # update other models here`

在2)我做:

pvp_player = ndb.Key(Profile, "test_id", PVPPlayer, "test_id").get()
return pvp_player.points`

我的流程如下:

1) update_points()
2) get_points()
3) update_points()
4) get_points()`
...

问题

使用get()可以保证强大的一致性,所以我不明白为什么有时候get_points()我得到像点这样的陈旧数据的结果根本没有更新。

示例

POST get_points -> 0
POST sleep 1-3 sec
POST update_points -> 15
POST sleep 1-3 sec
POST get_points -> 15
POST sleep 1-3 sec
POST update_points -> 20
POST sleep 1-3 sec
POST get_points -> 15 !!!`

2 个答案:

答案 0 :(得分:2)

首先检查你的日志,其中一个更新必须失败并出现错误,因为你的逻辑基本上是正确的。

同时仔细检查所有更新是否包含在交易中以避免比赛。 Cloud Datastore: ways to avoid race conditions

这种情况可能不是关于一致性问题,而是重写更新,请查看此链接以了解一些有趣的案例:

http://engineering.khanacademy.org/posts/transaction-safety.htm http://engineering.khanacademy.org/posts/user-write-lock.htm

答案 1 :(得分:1)

是否存在超过每个实体组写入限制的情况,即每秒更新一次?我认为这可能会破坏文档中提到的实体组的强一致性。