Задержка хранилища данных при создании объектов с помощью put()

#python #google-app-engine #google-cloud-datastore #app-engine-ndb

#python #google-app-engine #google-cloud-хранилище данных #app-engine-ndb

Вопрос:

Я разрабатываю приложение, используя эмулятор облачного хранилища данных (2.1.0) и библиотеку Python google-cloud-ndb (1.6).

Я обнаружил, что существует периодическая задержка при извлечении объектов с помощью запроса.

Например, если я создам объект, подобный этому:

 my_entity = MyEntity(foo='bar')
my_entity.put()

get_my_entity = MyEntity.query().filter(MyEntity.foo == 'bar').get()
print(get_my_entity.foo)
  

это приведет к сбою itermittently, потому get() что метод возвращает None .

Это происходит только примерно при 1 из 10 вызовов.

Чтобы продемонстрировать, я создал этот скрипт (также доступный с готовой к запуску настройкой docker-compose на GitHub):

 import random

from google.cloud import ndb
from google.auth.credentials import AnonymousCredentials


client = ndb.Client(
    credentials=AnonymousCredentials(),
    project='local-dev',
)


class SampleModel(ndb.Model):
    """Sample model."""
    some_val = ndb.StringProperty()


for x in range(1, 1000):
    print(f'Attempt {x}')
    with client.context():
        random_text = str(random.randint(0, 9999999999))
        new_model = SampleModel(some_val=random_text)
        new_model.put()

        retrieved_model = SampleModel.query().filter(
            SampleModel.some_val == random_text
        ).get()
        print(f'Model Text: {retrieved_model.some_val}')

  

Каков был бы правильный способ избежать этого прерывистого сбоя? Есть ли способ гарантировать, что объект всегда доступен после put() вызова?

Обновление Я могу подтвердить, что это проблема только с эмулятором хранилища данных. При тестировании на app Engine и Firestore в режиме хранилища данных объекты доступны сразу после вызова put() .

Комментарии:

1. Происходит ли это, если вы извлекаете объект через его id или key ? Например SimpleMOdel.get_by_id(<some-id>) , или entity.key().get() (проверьте синтаксис, я некоторое время не использовал хранилище данных)

2. @snakecharmerb только что протестирован, и нет, проблема не возникает при использовании SampleModel.get_by_id(int_id) … Это заставляет меня думать, что проблема заключается в задержке индексации. Интересно, есть ли способ принудительно выполнить индексацию?

3. Возможно, он пытается имитировать возможную согласованность?

4. @snakecharmerb только что просмотрел это, и есть флаг --consistency , который можно установить 1.0 , чтобы отключить это… Однако проблема все еще сохраняется.

5. Исправление: я неправильно применил изменение… --consistency=1.0 устраняет проблему.

Ответ №1:

Оказалось, что проблема связана с эмулятором, пытающимся воспроизвести конечную согласованность.

В отличие от реляционных баз данных, хранилище данных не гарантирует, что данные будут доступны сразу после их публикации. Это связано с тем, что часто возникают задержки репликации и индексации.

Для таких вещей, как модульные тесты, это можно решить, перейдя --consistency=1.0 к datastore start команде, как описано здесь .