2012-05-27 2 views
1

Я пытаюсь склонить голову к конфликту и как это относится к стеке приложений.Избегайте конкуренции в AppEngine

У меня есть модель, которая строить как так

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) 

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

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

спасибо.

ответ

1

Я не вижу никаких проблем с вашей моделью:

  1. Events лицо не будет платить налог конкурирующего, как кажется, judgding от ваших слов и, например, только корневыми юридических лиц за пределами каких-либо групп сущностей.
  2. Частое обновление для одного объекта может вызвать конфликт, но я вряд ли сомневаюсь, что владелец обновит любое сущность более одного раза в секунду (1QPS - это порог, который вы должны иметь в виду, выше того, что вы находитесь в опасной зоне).
  3. Операции чтения хранилища данных не вызывают конфликта.
2

Я тоже новичок в Google App Engine. поэтому в основном избегая споров, на самом деле спрашивают, как увеличить пропускную способность записи. Решения я мог думать, являются:

  1. Sacrifice Операции
  2. Batch Записывает в Memcached
  3. осколок счетчики
  4. Фоновые задачи очереди

https://developers.google.com/appengine/articles/sharding_counters

https://developers.google.com/appengine/articles/scaling/contention

Любая другая идея? Я тоже хотел бы знать!

+0

1. Сделки не имеют никакого отношения к ограничению записи. 2. Batching - да, путем сохранения на бэкэнд-экземплярах? 3. Sharding - улучшает запись, но не позволяет одновременное чтение. 4. То же, что 3. –

1

В вашем случае ограничение, которое применяется, - ограничение на запись/обновление сущности, которое составляет 1 запись/обновление на сущность (или группу сущностей) в секунду.

Для чтения нет ограничений.

По-прежнему рекомендуется использовать memcache для чтения кеширования, чтобы снизить стоимость и улучшить время отклика. Если вы используете Python NDB, то caching is enabled by default.

Решение: IMHO - хорошее решение для увеличения пропускной способности записи и одновременно имеет чтение backends. Они (в основном) всегда находятся в экземплярах, которые можно использовать в качестве общей памяти. Таким образом, вы можете выполнять пакетную запись (и очищать через очередь задач) при одновременном считывании.

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

1

В App Engine каждый экземпляр события считывается/записывается как целый объект. Вы были бы обеспокоены разногласием по каждому событию Event. Если вы должны часто обновлять один экземпляр события, вам может потребоваться беспокоиться о конфликте. Если вы обновляете разные экземпляры, тогда вам не о чем беспокоиться.

Я не уверен, что именно вы имеете в виду под давлением. Вы можете либо ссылаться на a) целостность транзакции, либо b) ограниченную производительность записи. У вас не должно быть проблем с чтением, хотя у вас есть проблема с возможной согласованностью.

a) Если вы должны прочитать правильные данные после того, как экземпляр события был обновлен, вам необходимо использовать запрос на получение данных() по ключевому слову. Запрос() может возвращать старые данные.

b) Если вы беспокоитесь о производительности записи, вам нужно как-то разделить свою сущность на несколько объектов. Вы, возможно, учитывая наличие нескольких объектов полезной нагрузки для каждого события, что-то вроде:

class Payload(db.Model): 
    event = db.ReferenceProperty(Events) 
    payload = db.StringProperty() 

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