4

Python と ndb を使用して作業を行っていますが、その理由がわかりません。ケースと上記のコードを投稿します。

models.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 オプションで実行されています。

テスト 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) を追加しましょう。

テスト 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 のテーブルに展開する時間をエミュレートしていると仮定しましょう。コードをスリープ状態にすることはありません。それでは、スリープを削除して親を追加しましょう!

テスト 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')

今、それは紛らわしいです!親を設定するだけで、強い一貫性が得られます! なんで ?また、強い一貫性を確保するために必要な場合は、デフォルトで、データストアに挿入するときにすべてのドキュメントを同じ親にしないのはなぜですか? 多分私はそれを完全に間違っており、それをより良くする方法があります。お願いします、誰か私を導いてください!

前もって感謝します

4

1 に答える 1

7

祖先クエリは同じエンティティ グループ (したがって物理的に近い) で動作し、強い一貫性があります。

テスト 1 では、HRD は put() を認識しない可能性があります。これは、分散されているため結果的に一貫性があるためです。

テスト 2 では、HRD が一貫性を保つのに十分な時間があるため、クエリにエンティティが表示されます。

テスト 3 では、同じエンティティ グループに配置して、強い整合性を確保します。

Q : すべてを同じエンティティ グループに含めないのはなぜですか?
A : 多数のエンティティ グループが存在しない限り、GAE は大規模なデータセットを配布できません (その後、多数の異なるサーバーにそれらをプッシュできます)。エンティティ グループは、必要なだけ大きくする必要があります (G は、ユーザー オブジェクトの下にユーザーの「メッセージ」を配置する例を使用する場合があります)。また、エンティティ グループのメンバーに書き込むとグループ全体がロックされるため、書き込み速度の制限に直面します (1 秒あたり 1 回の書き込みなど)。

Q : 私の get() はオブジェクトを取得しませんでしたか?
A : いいえ、キーによる get のみが強い一貫性を持っています。実際には LIMIT 1 の省略形である query().get() を実行しました。

于 2013-01-31T19:20:27.473 に答える