2009-12-25 2 views
2

Так что я прочитал все RMDB против BigTable дебатыApp Engine Простая игра Модель Эксперимент (Scalable)

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

Цели: Обеспечить очень быстро читает и значительно легко пишет

Сценарий: У меня есть 500000 объектов пользователя в моей модели пользователя. Мой пользователь видит статистику пользователя в верхней части своей страницы (подумайте о статусной строке, как в 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, нет МНОГИЕ-МНОГИЕ отношения
3. Обновления очень легко выполняются: просто получите пользовательский объект по имени
4. Легко передать запрошенный объект на шаблонный двигатель.

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

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

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

В сущности, все, что здесь идет против RMDB

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

ответ

1

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

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

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

+0

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

1

Вы должны создать независимые модели для своих устройств. «Хотя одна группа сущностей или сущностей имеет ограничение на то, как быстро она может быть обновлена, App Engine отлично справляется с обработкой многих параллельных запросов, распределенных по отдельным объектам, и мы можем воспользоваться этим, используя sharding». Have a look at this article. Это может быть полезно.

+0

Ему нужен только один тип/модель/класс устройства. Тогда у него может быть столько случаев, сколько он хочет. По умолчанию каждая из них будет находиться в своей собственной группе лиц. –

0

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

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 

и да, все unit_types будет Memcached, так что они могут быть получены для быстрого вычисления общих точек атаки.

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

+0

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

Смежные вопросы