Сильная согласованность, когда вам нужно запросить несколько объектов (тысяч) - PullRequest
1 голос
/ 13 марта 2019

В приложении, которое имеет много «магазинов», каждый зарегистрированный пользователь-администратор имеет сущность «магазин», каждый магазин продает товары, в которых каждый товар относится к определенной « категории ». Наличие нескольких клиентов (в некоторых случаях по 100) каждый клиент имеет учетную запись для отслеживания своих покупок и прошлых заказов. Каждый магазин генерирует счета для своих клиентов, клиенты оплачивают счета.

Admin User -- > Shop 

Shop ---> clients
      |-> items Categories
      |-> items
      |-> invoices
      |-> payments received

На странице администратора отображается отчет, показывающий счета в течение года (с января по декабрь), эта страница является требованием клиента. Магазин может вручную сгенерировать новый счет-фактуру при совершении покупки и записать платеж при его оплате. Примечание: все это происходит в реальном магазине, нет покупок через Интернет.

Поскольку один магазин генерирует несколько счетов в месяц (~ 100) и несколько платежей в месяц (~ 100), показ этой суммы в год легко дается тысячам организаций для отображения на одной странице.

Чтобы оптимизировать загрузку страницы и создание отчета о продажах за год (общий объем продаж, выручка, оплата и т. Д.), Мы решили структурировать данные таким образом, чтобы каждая категория товара в год также является юридическим лицом. Это означает, что всякий раз, когда совершается покупка для элемента в этой категории, нам нужно добавить цену покупки элемента к itemCategory в этом году в этом месяце.

itemCategory Модель:

itemCategory(ndb.Model):
    shopID = ndb.KeyProperty()
    year = ndb.IntegerProperty()
    monthly_sales = ndb.FloatProperty(repeated=True) #12 months

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

Category      Jan   Feb   Mar ... Dec
--------------------------------------
Men's shoes   1000  1300  850 ... 1400
Kids shoes     600   850  650 ...  900

Сложность в этой точке заключается в том, что очень важна строгая согласованность для отдельных покупок и для сущностей itemCategory. Потому что, если магазин пытается добавить несколько покупок последовательно коротким временем, с возможной согласованностью itemCategory может еще не обновиться с последней суммой покупки. В результате неправильные значения продаж. Также то же самое для отдельной покупки, если было требование отредактировать одну сразу после ее добавления, запрос для объекта без его идентификатора может не иметь результатов. Таким образом, кажется, что запросы Ancestor здесь важны, возможно, магазин как родительский объект. Тем не менее, это приведет к конфликту позже (по крайней мере, до тех пор, пока Datastore не будет перенесен в Firestore), когда все эти сущности (в данном случае тысячи!) Имеют одного родителя!

То же самое касается счетов-фактур, генерация нового счета-фактуры означает знание последнего номера счета-фактуры, чтобы они всегда были в последовательности без пропусков. Запрос счета с возможной согласованностью может привести к дублированию номеров счетов.

Каков оптимальный способ структурирования данных на данном этапе для обеспечения строгой согласованности? К сожалению, проект был там в течение нескольких лет, и был начат с использованием Google Datastore, а не Cloud SQL (что кажется более подходящим для такого рода проектов). Надеемся, что все эти проблемы исчезнут после перехода на Firestore, который будет иметь строгую согласованность для всех операций чтения

Ответы [ 2 ]

1 голос
/ 13 марта 2019

Подумайте об экспорте данных, а затем о импорте их в хранилище Cloud Firestore в проекте режима хранилища данных. Больше никаких возможных проблем с консистенцией.

0 голосов
/ 13 марта 2019

Существуют определенные способы достижения сильной согласованности.

  1. Запрос с использованием key.Всякий раз, когда вы пытаетесь прочитать объект с помощью его ключа, это strongly consistent.
  2. Другой подход заключается в использовании асинхронных операций NDB.См. Соответствующую документацию здесь.
  3. Действительно наивным подходом было бы предоставить задержку, которая могла бы помочь вам, но задержка должна предоставляться таким образом, чтобы онадостаточно для обновления объекта.
  4. И последний подход может заключаться в экспорте данных в Cloud Firestore.Там вы всегда можете достичь сильной последовательности.

Надеюсь, что это ответ на ваш вопрос !!!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...