Как стать автором
Обновить

Комментарии 28

В прошлом проекте были 10-15 тысяч игроков онлайн. Цель текущей реализации держать это число без особых проблем.
За счет масшабируемости мы можем увеличивать количество обработчиков, шардировать базу и кэш. Так что узкие моменты производительности на мой взгляд решены.
Расскажите пожалуйста как вы масштабируете кеш и какие данные там хранятся?
Практически все данные имеют связь с user_id.
Шардирование базы строется по user_id. К примеру 1-1000 в первую базу, 1001-2000 во вторую базу.
Аналогично с кэшем. Просто запущено несколько memcached на разных серверах.
Кешируются данные моделей, а точнее атрибуты (поля из базы)
В кеше лежат одинаковые данные или тоже шардинг? Обращаться можно к любому серверу кеша или по шардингу?
Тоже шардинг. Принцип тот же. Я получаю данные из кэша стандартными методами проекта, а внутри все разруливается и определяется с какого сервера тянуть.
1-1000 в первую базу, 1001-2000 во вторую базу

Игроки ведь уходят когда-то. Таким образом есть шанс, что через некоторое время игроки с первого сервера уйдут, но несколько останется и для них придется держать целый сервер. Почему не остаток от деления user_id на числов серверов? Просто интересно.
А, что-то я бред написал. Да, ваш вариант интересный. Возможно изменим логику. Спасибо :)
Все правильно написал. Если у меня user_id = 100, при 5ти шардах, я буду попадать на 0вую шарду, добавляем 6той сервер, я попаду уже явно на другой шард, а там моих данных нет.
Связка генерируется в момент создания user_id и сохраняется в таблицу, которая не шардируется. Потом из нее узнаем где лежит пользователь. Так что все ок :)
На самом деле не бред написал. Используйте консистентый хеш, вот статья на хабре на примере мемкеша habrahabr.ru/post/42972/
Не «остаток от деления user_id на числов серверов», потому что это негибко, и пользователей на другую шарду перетащить будет сложно в случае необходимости.
А в случае принятого решения, путем небольшого улучшения компонента, отвечающего за шардирование, можно будет неактивных пользователей перенести в шард на слабеньком сервере
Потому что умеем готовить с ним вкусные штуки
По примеркам потребуется до 20 секунд для того, чтобы выполнить все команды игрока, что допустимо.
Ну ничего себе у вас допущения.

3. клиент валидирует их, но не отправляет на сервер, а накапливает у себя
4. по достижении какого-либо условия клиент отправляет на сервер все эти команды пачкой
А если я, скажем, совершу ряд действий и со спокойной душой закрою клиент? Получается, весь прогресс потеряется, если пачка ещё не успела отправиться на сервер? Какой-то сомнительный подход, на мой взгляд.
Только если вы выключите телефон или игра упадет. В остальных случаях данные будут отправлены. Игры делается для мобильников
А можно кратко про mongo, как решили проблемы с лагами, и из-за чего они возникали?
Проблемы решили путем снижения нагрузки на mongodb и отключением части шар. Когда уменьшили количество шар с 5 до 3, то стало несколько легче. Почему так получилось не ясно. Это был первый опыт использования mongodb. Возможно не знаем каких-то тонкостей настройки.
10-15 к на среднестатическом сервер (2.3  xeon, 4gb ram) можно выдержать другой схемой.
Каждая комманда посылается на сервер, который в свою очередь держит в памяти состояние пользователя и при запросе клиента валидирвует запрос и производит транзакцию (в памяти). И когда пользователь выходит, либо когда совершаются действия с золотом(реалом), состояние дампится в базу.
Эта схема у нас используется в другом проекте, у которого на стороне сервера nodejs, которая постоянно в памяти и там постоянно держится соединение с сервером.
У нас же nginx + php. Скрипт после отработки ничего в памяти не оставляет.
Ну в случае с php можно делать на php daemon, но вообще erlang для этой задачи подходит лучше всего ;-)
Согласен, что вариантов решения много. Я привел тот, который был выбран в связи с тем, что мы знаем как его реализовать качественно и в нужные сроки.
1) С какой периодичностью клиент отправляет данные на сервер?
2) Не случается ли так, что пользователь ничего не «накручивает», играет честно, клиент все действия пользователя выполняет, а при очередной отправке на сервер приходит ложная ошибка, связанная с какой-нибудь недоработкой/апгрейдом/мало ли чем? Ведь игрок уже может много чего сделать, а его состояние сброситься на исходное. Как уходите от подобных возможных проблем?
3) Насколько близко логика работы расположена к уровню БД? Используете ли ХП, если нет — почему?
1) частота отправки будет опытным путем подбираться. К примеру 10 команд накопилось — скинули. Или раз в 5 минут.
2) Такое возможно. Уходим от такого с помощью тестов, которые покрывают логику приложения и снижают риск возникновения такой ситуации.
3) В бд логики никакой нет. Каких-либо связей между таблицами в самом бд не реализовано. Все довольно просто там.
А что за ХП?
Хранимые процедуры
ага, ничего такого не используем
У нас была такая схема
www.youtube.com/watch?v=oyvIDklWxyk

Весь мир симулировался на клиенте так же как на сервере.

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