App Engine Эксперимент по простой игровой модели (масштабируемый) - PullRequest
2 голосов
/ 25 декабря 2009

Итак, я прочитал все обсуждения RMDB против BigTable

Я пытался смоделировать простой игровой класс, используя концепции BigTable.

Цели: обеспечить очень быстрое чтение и достаточно легкую запись

Сценарий: у меня 500 000 пользовательских объектов в моей модели User. Мой пользователь видит статистику пользователя вверху своей игровой страницы (подумайте о строке состояния, как в Mafia Wars), поэтому везде, где он / она заходит в игру, статистика обновляется.

Так как он вызывается так часто, почему бы мне не смоделировать моего Пользователя вокруг этого факта?

Код:

# simple User class for a game
class User(db.Model):
  username = db.StringProperty()

  total_attack = db.IntegerProperty()

  unit_1_amount = db.IntegerProperty()
  unit_1_attack = db.IntegerProperty(default=10)

  unit_2_amount = db.IntegerProperty()
  unit_2_attack = db.IntegerProperty(default=20)

  unit_3_amount = db.IntegerProperty()
  unit_3_attack = db.IntegerProperty(default=50)

  def calculate_total_attack(self):
    self.total_attack = self.unit_1_attack * self.unit_1_amount + \
                        self.unit_2_attack * self.unit_2_amount + \
                        self.unit_3_attack * self.unit_3_amount + \

вот как я к нему подхожу (не стесняйтесь комментировать / критиковать)

Преимущества:
1. Все в одном большом столе
2. Нет необходимости использовать ReferenceProperty, нет отношений MANY-TO-MANY
3. Обновления выполняются очень легко: просто получите пользовательский объект по ключевому слову
4. Легко перенести запрашиваемую сущность в движок шаблонов.

Недостатки:
1. Если у меня есть 100 различных юнитов с разными возможностями (атака, защита, ловкость, магия и т. Д.), У меня будет очень ОГРОМНЫЙ стол.
2. Если мне нужно изменить значение определенной единицы атаки, то мне придется пройти через все 500 000 пользовательских сущностей, чтобы изменить каждую из них. (возможно, очередь заданий / задач cron поможет)

Каждый объект будет иметь размер 5-10 КБ (кстати, как мне проверить, насколько велик объект, когда я загрузил его на рабочий сервер?).

Так что я рассчитываю на то, что дисковое пространство в App Engine дешевое, и мне нужно минимизировать количество вызовов API хранилища данных. И я постараюсь запоминать сущность на некоторое время.

По сути, все здесь идет вразрез с RMDB

Хотелось бы услышать ваши мысли / идеи / опыт.

Ответы [ 3 ]

1 голос
/ 26 декабря 2009

Вы должны создавать независимые модели для ваших юнитов. «Хотя у одной сущности или группы сущностей есть ограничение на скорость ее обновления, App Engine отлично справляется с обработкой многих параллельных запросов, распределенных между разными сущностями, и мы можем воспользоваться этим с помощью шардинга». Посмотрите на эту статью . Это может быть полезно.

1 голос
/ 26 декабря 2009

Сначала простой ответ на вопрос «как узнать, насколько велика сущность?»: После того, как вы получили данные в своем приложении на серверах механизма приложений, вы можете перейти к консоли своего приложения. и нажмите ссылку «Статистика хранилища данных». Это даст вам некоторую базовую статистику по вашим сущностям, например, сколько места использует каждый тип, какие типы свойств используют больше всего дискового пространства и т. Д. Однако я не думаю, что вы сможете перейти к уровню одного конкретного пользователя.

Теперь вот несколько соображений по поводу вашего дизайна. Стоит создать отдельную таблицу для ваших юнитов. Даже если у вас будет несколько сотен юнитов, будет легко сохранить их все в memcache, поэтому поиск деталей каждого юнита будет незначительным. Это будет стоить вам несколько дополнительных вызовов API, чтобы изначально заполнить memcache информацией о модуле при первом его использовании, но после этого вы сэкономите значительное количество циклов ЦП, поскольку вам не придется извлекать сведения о каждом модуле из базы данных. и сохранение огромного количества вызовов API, когда вам нужно обновить модуль (что вы уже поняли, будет очень дорого). Кроме того, каждый объект User будет использовать меньше дискового пространства, если ему нужна только ссылка на объект Unit, а не удержание все детали сама. (Конечно, это зависит от количества информации, которое вам нужно хранить о каждом отряде, но вы упомянули, что в конечном итоге вы будете хранить много статистики для каждого отряда)

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

0 голосов
/ 27 декабря 2009

исходя из мыслей Питера, я придумал следующую пересмотренную модель пользователя. Что вы, люди, думаете?

class Unit(db.Model):
  name = db.StringProperty()
  attack = db.IntegerProperty()

#initialize 4 different types of units
Unit(key_name="infantry",name="Infantry",attack=10).put()
Unit(key_name="rocketmen",name="Rocketmen",attack=20).put()
Unit(key_name="grenadiers",name="Grenadiers",attack=30).put()
Unit(key_name="engineers",name="Engineers",attack=40).put()

class User(db.Model):
  username = db.StringProperty()

  # eg: [10,50,100,200] -> this represents 10 infantry, 50 rocketmen, 100 grenadiers and 200 engineers
  unit_list_count = db.ListProperty(item_type=int)

  # this holds the list of key names of each unit type: ["infantry","rocketmen","grenadiers","engineers"]
  unit_list_type = db.StringListProperty()

  # total attack is not calculated inside the model. Instead, I will use a
  # controller file ( a py file ) to call the contents of unit_list_count and 
  # unit_list_type of a certain user entity, and make simple multiplications and additions to get total attack

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

Хотелось бы услышать все мысли по этому поводу.

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