AppEngine实现强一致性
AppEngine achieving strong 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 !!!`
是否存在超出每个实体组写入限制的情况,即每秒更新一次?我认为这可能会破坏文档中提到的实体组的强一致性。
首先检查你的日志,肯定有一个更新失败并出错,因为你的逻辑基本上是正确的。
还要仔细检查所有更新都包含在事务中以避免竞争。
这个案例可能不是关于一致性问题,而是关于更新,检查这个链接以了解一些有趣的案例:
http://engineering.khanacademy.org/posts/transaction-safety.htm
http://engineering.khanacademy.org/posts/user-write-lock.htm
我正在努力实现强一致性。让我们称我的模型为 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 !!!`
是否存在超出每个实体组写入限制的情况,即每秒更新一次?我认为这可能会破坏文档中提到的实体组的强一致性。
首先检查你的日志,肯定有一个更新失败并出错,因为你的逻辑基本上是正确的。
还要仔细检查所有更新都包含在事务中以避免竞争。
这个案例可能不是关于一致性问题,而是关于更新,检查这个链接以了解一些有趣的案例:
http://engineering.khanacademy.org/posts/transaction-safety.htm http://engineering.khanacademy.org/posts/user-write-lock.htm