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

ndb强一致性和频繁写入

尉迟正平
2023-03-14

我正在尝试使用python与ndb实现强一致性。看起来我错过了一些东西,因为我的读取表现得好像它们不太一致。

查询是:

links = Link.query(ancestor=lead_key).filter(Link.last_status == 
None).fetch(keys_only=True)

if links: 
    do_action() 

关键结构是:

Lead root (generic key) -> Lead -> Website (one per lead) -> Link

我有许多使用TaskQueue同时执行的任务,并且此查询在每个任务结束时执行。有时我在更新last_status字段时会遇到“过多争用”异常,但我会使用重试来处理它。它会破坏强一致性吗?

预期的行为是,当没有剩余的链接的最后一个\u状态等于无时,调用了do\u action()。实际行为是不一致的:有时调用两次,有时根本不调用。

共有3个答案

柯奕
2023-03-14

示例中没有任何内容可以确保代码只被调用一次。

目前,我假设您的“do\u action”函数对链接实体做了一些事情,特别是它设置了“last\u status”属性。

如果不在事务中执行查询和对链接实体的写入,则两个不同的请求(任务队列任务)可能会从查询中获取结果,然后将其新值写入链接实体(最后一次写入会覆盖以前的值)。

请记住,即使您确实使用了事务,在事务成功完成之前,您也不知道没有其他人尝试执行写入。如果您尝试执行数据存储之外的操作(例如,向外部系统发出超文本传输协议请求),这一点很重要,因为您可能会看到来自事务的超文本传输协议请求最终会因并发修改异常而失败。

乐正嘉瑞
2023-03-14

添加到戴夫的答案是第一件要检查的事情。

有一件事没有很好的文档记录,可能有点令人惊讶,那就是争用也可能是由读操作引起的,而不仅仅是由写操作引起的。

每当事务启动时,被访问的实体组(通过读取或写入操作,没关系)都会被标记为这样。太多争用错误表明太多并行事务同时尝试访问同一个实体组。即使没有任何事务实际尝试写入,也可能发生!

注意:开发服务器不会模拟此争用,只有在GAE上部署真实的数据存储时才能看到它!

更令人困惑的是事务的自动重试,这可能发生在实际的写入冲突或简单的访问争用之后。这些重试在最终用户看来可能是某些代码路径的可疑重复执行——我怀疑这可以解释您关于调用两次do_action()的报告。

通常,当您遇到此类问题时,您必须重新访问您的数据结构和/或访问它们的方式(您的事务)。除了保持强一致性的解决方案(这可能非常昂贵)之外,您可能还需要重新检查一致性是否真的是必须的。在某些情况下,它被添加为一揽子要求只是因为看起来简化了事情。根据我的经验,它没有:)

隆扬
2023-03-14

使用祖先键来获得强一致性有一个限制:每个实体组每秒只能更新一次。解决这个问题的一种方法是对实体组进行分片。分片计数器描述了这种技术。这是一篇旧文章,但据我所知,建议仍然合理。

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

  • 我使用将整个代码库从更改为 由于节俭,我从一开始就经常超时,我无法继续...采用CQL,按照我成功设计的表格和更少的超时.... 有了这个,我能够插入大量不符合节俭原则的数据…但是经过一个阶段,数据文件夹大约在3.5GB左右。我经常遇到写入超时异常。即使我再次做同样的早期工作用例,现在也会引发超时异常。它的随机曾经工作过,即使在重新设置后也无法再次工作。 CASSADNRA服务器日志 这是卡桑德拉

  • 我正在努力实现强烈的一致性。让我们调用我的模型PVPPlayer: 模型的每个关键点都是这样创建的: 其中,配置文件是父模型: 我有2个REST api url: 在1)我做: 在2)我做: 我的流程如下所示: 问题: 使用保证了很强的一致性,所以我不明白的是为什么有时由于,我得到了一些陈旧的数据,比如点根本没有更新。 示例:

  • 我最近把我的应用上传到了谷歌Playstore。我使用错误报告器跟踪崩溃。应用程序工作正常,但经常出现HttpHostConnectException。在进行每次网络通话之前,我都会检查互联网连接。造成这一例外的原因还有其他原因吗?如何避免? 附言:在测试/调试我的应用程序时,我从来没有遇到过这个异常。

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

  • 本文向大家介绍python频繁写入文件时提速的方法,包括了python频繁写入文件时提速的方法的使用技巧和注意事项,需要的朋友参考一下 问题背景:有一批需要处理的文件,对于每一个文件,都需要调用同一个函数进行处理,相当耗时。 有没有加速的办法呢?当然有啦,比如说你将这些文件分成若干批,每一个批次都调用自己写的python脚本进行处理,这样同时运行若干个python程序也可以进行加速。 有没有更简单