Как избежать раздоров в AppEngine
Я пытаюсь обернуть голову в борьбу и то, как она применяется к стеку Application Engine.
У меня есть модель, которая построена так
class Events(db.Model):
#Owner Identification Number
owner_id = db.StringProperty(required=True)
#Authentication Token
auth_token = db.StringProperty(required=True)
#generic, b, c, d, ...
driver = db.StringProperty(required=True)
#Start Time and Date
tStart = db.DateTimeProperty(auto_now=True)
#Define whether the event is active or inactive
active = db.BooleanProperty(default=False)
#Payload store, this will store each payload block sent or pulled
payloads = db.StringListProperty(indexed=False)
Эта модель содержит несколько событий, каждое событие имеет владельца и полезные нагрузки, владелец события будет записывать полезные нагрузки в его событие и из него, а многие другие будут читать из события, это своего рода стек транскрипции.
У меня вопрос о споре, повлияет ли это на меня, и если да, то как мне реструктурировать, чтобы предотвратить это.
Спасибо.
4 ответа
Я не вижу никаких проблем с вашей моделью:
Events
Субъекты не будут платить уплаченный налог, как вам кажется, судя по вашим словам и примеру, просто корневые сущности вне какой-либо группы сущностей.- Частое обновление одного объекта может вызвать конфликт, но я вряд ли сомневаюсь, что владелец будет обновлять любой объект чаще, чем один раз в секунду (1QPS - это пороговое значение, которое вы должны учитывать, выше того, что вы находитесь в опасной зоне).
- Операции чтения хранилища данных не вызывают проблемы конфликта.
Я новичок в Google App Engine тоже. таким образом, в основном, избегая конфликта, фактически спрашивают, как увеличить пропускную способность записи. Решения, о которых я мог подумать:
- Жертвоприношения
- Пакетная запись в memcached
- Счетчики осколков
- Очередь фоновых задач
https://developers.google.com/appengine/articles/sharding_counters
https://developers.google.com/appengine/articles/scaling/contention
Любая другая идея? Я тоже хотел бы знать!
В App Engine каждый экземпляр события читается / записывается как целый объект. Вы будете беспокоиться о разногласиях в каждом случае события. Если вам необходимо часто обновлять один экземпляр события, вам, возможно, придется беспокоиться о конфликте. Если вы обновляете разные экземпляры, вам не о чем беспокоиться.
Я не уверен, что именно вы имеете в виду под утверждением. Вы можете ссылаться на а) целостность транзакции или б) ограниченную производительность записи. У вас не должно быть проблем с производительностью чтения, хотя у вас есть проблема с конечной согласованностью, с которой нужно иметь дело.
a) Если вам необходимо прочитать правильные данные после обновления экземпляра Event, вам необходимо использовать запрос get() хранилища данных по ключу. Запрос query() может вернуть старые данные.
б) Если вас беспокоит производительность записи, вам нужно как-то разделить вашу сущность на несколько сущностей. Возможно, вы можете рассмотреть возможность использования нескольких сущностей полезной нагрузки для каждого события, например:
class Payload(db.Model):
event = db.ReferenceProperty(Events)
payload = db.StringProperty()
Таким образом, вы можете написать каждую полезную нагрузку отдельно, но это будет немного дороже, поскольку они должны быть проиндексированы, и вам нужно будет запросить их по событию, чтобы получить их. Возможно, вы захотите установить Событие в качестве предка, чтобы вы могли использовать запросы предка для согласованных запросов.
В вашем случае применяется ограничение на запись / обновление объекта, которое составляет 1 запись / обновление на объект (или группу объектов) в секунду.
Нет ограничений для чтения.
По-прежнему хорошая идея использовать memcache для кэширования чтения, чтобы снизить затраты и сократить время отклика. Если вы используете Python NDB, то кэширование включено по умолчанию.
Решение: ИМХО хорошее решение для увеличения пропускной способности записи и одновременного чтения является бэкэндом. Они (в основном) всегда в тех случаях, когда вы можете использовать их в качестве общей памяти. Таким образом, вы можете выполнять пакетную запись (и очистку через очередь задач) при одновременном чтении.
Примечание. Экземпляры перезапускаются примерно раз в день, поэтому вы не можете рассматривать их как надежное хранилище - вы можете использовать их как интеллектуальный кэш, в то время как асинхронно (через внутренние потоки или очередь задач) транзакционно обновляет сущность в хранилище данных.