当前位置: 首页 > 知识库问答 >
问题:

AppEngine实现强一致性

姜飞飙
2023-03-14

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

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

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

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

其中,配置文件是父模型:

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个答案

赵晨
2023-03-14

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

廉元龙
2023-03-14

首先检查您的日志,其中一个更新肯定会出错,因为您的逻辑基本正确。

还要仔细检查所有更新是否包装在事务中,以避免竞争。云数据存储:避免竞争条件的方法

这个案例可能不是关于一致性问题,而是践踏更新,查看以下链接以获取一些有趣的案例:

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

 类似资料:
  • 我有一个这样的模型: 由于以上字段都不是唯一的,所以电子邮件也不是唯一的,因为许多人可能没有电子邮件ID。因此,我使用以下逻辑创建字符串id 我使用get_or_insert插入实体。 虽然添加用户不会经常发生,但任何冲突都会是灾难性的,这意味着竞争的可能性较小,但其影响非常大。 我的问题是: PS:出于几个原因,我不能将所有用户实体保留在同一个实体组中。

  • 这是我的简单实体: 我以这种方式加载我的食物清单: Key是为每个Food实体自动生成的。我也在使用HRD。因此...上面的查询(pm.newQuery(Food.class);)不具有很强的一致性,一次返回所有结果,第二次不返回新创建的食物。如何以这种方式更改此查询,以至于每次我从数据库中获取所有食物。在datastore留档中,我读过应该是祖先查询,但我没有祖先路径。(我应该说我是datast

  • 我想运行这个计划,以实现与我的GAE结构的高度一致性。目前,我有以下内容(我保证,这真的很简单): 您有一个类(类的意思是课堂不是编程“类”)模型和一个作业模型,还有一个用户模型。现在,一个类有一个名为MemberID的整数列表属性,它是一个用户ID的索引列表。类还具有赋值ID的字符串列表。 每当创建一个新的分配时,其相应的类实体也会更新,并将新的分配id添加到其列表中。 我想做的是为用户获取新的

  • 我有一个3节点的Cassandra集群,其密钥空间的复制因子为3: (仅部署在一个数据中心) 当进行失败测试时,即关闭一个节点,我在尝试查询我的键空间时得到这些异常: 我不知道为什么会看到这个错误,因为: 我的复制因子设置为3(即我仍然有2个节点,每个节点包含所有数据) 我的一致性级别设置为QUORUM。(为什么我看到LOCAL_ONE?)

  • 使用CQRS和事件存储,微服务之间的编排提供了最终的一致性,其中一个微服务中的更改需要一点时间传播到其他相关的下游系统(本质上是其他微服务)。如果数据非常关键,以至于两个微服务都应该具有很强的数据一致性,那么有什么选择呢?我能想到的一个选择是像数据网格那样的直写缓存,但这非常脆弱,特别是在分布式系统中。

  • 我正在尝试使用appengine实现GCM。我创建并部署了默认的appengine后端GCM模板。我创建一个GCM注册id: 然后,我使用模板中的默认注册endpoint将这个regID存储在appengine上。我的广播接收器如下所示: 这是我的舱单: BroadCastReceiver和intent服务在我的项目中是独立的类。appengine后端GCM是一个单独的模块。创建此模块期间: 编译