ndb 和一致性:为什么在没有父级的查询中发生这种行为

2024-01-06

我正在使用 Python 和 ndb 做一些工作,但不明白为什么。我将发布上面的案例和代码:

模型.py

class Reference(ndb.Model):
  kind = ndb.StringProperty(required=True)
  created_at = ndb.DateTimeProperty(auto_now_add=True)
  some_id = ndb.StringProperty(indexed=True)
  data = ndb.JsonProperty(default={})

这些测试在交互式控制台和 dev_appserver.py 的 --high_replication 选项中运行:

Test 1

from models import Reference
from google.appengine.ext import ndb
import random

some_id = str(random.randint(1, 100000000000000))
key_id = str(random.randint(1, 100000000000000))

Reference(id=key_id, some_id=some_id, kind='user').put()
print Reference.query(Reference.some_id == some_id, Reference.kind == 'user').get()

# output:
# >> None

为什么 ?????现在,让我们在打印之前添加一个 sleep(1) :

Test 2

from models import Reference
from google.appengine.ext import ndb
import random
from time import sleep

some_id = str(random.randint(1, 100000000000000))
key_id = str(random.randint(1, 100000000000000))

Reference(id=key_id, some_id=some_id, kind='user').put()
sleep(1)
print Reference.query(Reference.some_id == some_id, Reference.kind == 'user').get()

# output:
# >> Reference(key=Key('Reference', '99579233467078'), createdAt=datetime.datetime(2013, 1, 31, 16, 24, 46, 383100), data={}, kind=u'user', some_id=u'25000975872388')

K,假设它正在模拟将文档传播到所有 Google 表的时间,我永远不会在我的代码中添加睡眠,ofc。现在,让我们删除睡眠并添加父级!

Test 3

from models import Reference
from google.appengine.ext import ndb
import random
from time import sleep

some_id = str(random.randint(1, 100000000000000))
key_id = str(random.randint(1, 100000000000000))

Reference(id='father', kind='father').put()

Reference(parent=ndb.Key(Reference, 'father'), id=key_id, some_id_id=some_id, kind='user').put()
print Reference.query(Reference.some_id == some_id, Reference.kind == 'user', ancestor=ndb.Key(Reference, 'father')).get()

# output:
# >> Reference(key=Key('Reference', '46174672092602'), createdAt=datetime.datetime(2013, 1, 31, 16, 24, 46, 383100), data={}, kind=u'user', some_id=u'55143106000841')

现在这很令人困惑!就设置一个parent,给我强一致性吧!为什么 ? 如果需要提供强一致性,为什么默认情况下在将其插入数据存储中时不让所有文档具有相同的父级? 也许我做得完全错误,并且有一种方法可以做得更好。请有人指导我!

提前致谢


祖先查询在同一实体组中运行(因此物理上接近)并且具有强一致性。

在测试 1 中,HRD 可能看不到 put(),因为由于其分布式特性,它最终是一致的。

在测试 2 中,HRD 有足够的时间变得一致,以便您在查询中看到实体。

在测试 3 中,您将其放置在同一实体组中,因此它是高度一致的。

Q:为什么不将所有内容都放在同一个实体组中?
A:GAE 无法分发大量数据集,除非有一堆实体组(然后他们可以将它们推送到大量不同的服务器)。实体组应该与您需要的一样大,并且不能更大(G 有时使用将用户“消息”放在用户对象下的示例)。另外,由于写入实体组的成员会锁定整个组,因此您面临写入速度限制(如果我记得的话,例如 1 次写入/秒,Alfred 有一个关于它的演讲)。

Q:我的 get() 没有获取对象,不是应该的吗?
A:不,只有 key 的 get 是强一致的,你做了一个 query().get() 这实际上只是 LIMIT 1 的简写。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ndb 和一致性:为什么在没有父级的查询中发生这种行为 的相关文章

随机推荐