Я хочу использовать базу данных sql в моем server.exe.
скажем, 1000 пользователей онлайн. И игроки будут менять свои данные, когда они играют. И на сервере нужно сохранить эти обновления.
Но как ?
я думаю, что есть два пути:
1) сервер будет сохранять в оперативной памяти во время выполнения, а иногда или ежечасно сервер будет записывать данные (обновление) в базу данных sql из оперативной памяти. Но если электричество отключится или сервер отключится, обновления не сохранятся. Конечно, я не хочу терять обновления.
2) сервер будет сохранять обновления в базе данных во время выполнения. но что будет со скоростью? Я думал о методе. Я покажу вам ниже с изображением. Могу ли я получить достаточную скорость для 1000 игроков онлайн с помощью этого метода?
источник
Ответы:
Большинство ММО (или проектов, использующих подобную архитектуру), над которыми я работал или знаю, используют первый метод: игровые серверы работают в основном с ОЗУ на машинах, на которых выполняются серверные процессы, и только периодически сериализуют соответствующие игровые данные в базу данных SQL. для архивирования (если он вообще используется).
Проблемы, с которыми вы сталкиваетесь при сбое питания, действительны, но менее вероятны, чем такие, как сбои в процессе (надежность времени безотказной работы, как правило, является одной из тех вещей, за которые вы платите центру обработки данных). Но до сих пор. Вы устраняете эти проблемы с помощью таких настроек, как настройка интервала сохранения (таким образом, сбой стоит всего несколько минут), распределение очередей сохранения по нескольким машинам, агрессивное определение объема данных, которые необходимо сохранить, и внедрение перезапускаемого сохранения. очереди.
Вообще говоря, использование самого SQL-сервера в качестве основной памяти будет неприятно медленным (и громоздким). Я не вижу достаточно подробностей в вашем предложении, чтобы можно было с уверенностью сказать, сработает ли это только для 1000 игроков - это, вероятно, будет хорошо. Но я не верю, что вы можете сделать это агрессивно масштабируемым.
Кроме того, это не решает проблему. Сбой питания во время процесса сохранения все равно приведет к потере или повреждению данных, если вы не выполните работу по реализации перезапускаемой очереди сохранения того же типа (которая даже тогда, которая лишь значительно снижает вероятность катастрофической потери данных, не предотвращает ее) ,
Я бы порекомендовал вам пойти с первого подхода.
источник
1000 игроков может или не может быть проблемой. Это зависит от того, как часто вам нужно обновлять базу данных. Однако есть простое решение: разместить базу данных на своем собственном сервере.
Я взглянул на то, как система баз данных работает в игре, которую люди назвали бы MMO-Lite - которую я не буду раскрывать, - но я могу сказать, что в ней постоянно более 1000 игроков, это реферат:
Использование базы данных на основе документов оказывается хорошей идеей для производительности в этом случае. Это хорошо для доступа к данным, хотя это плохо для выполнения объединений и агрегаций ... но они не будут делать это с данными, которые там находятся.
С другой стороны, когда им нужно сделать что-то, например, заменить объект другим объектом для всех, необходимость запустить фоновый скрипт, который идет символ за символом и обновляет их один за другим, это занимает заметное время.
Данные персонажа существуют как на клиенте, так и на сервере, и система предназначена для их синхронизации, выполняя одинаковые операции с обеих сторон.
Теперь, когда игрок совершает транзакцию с системой, скажем, обменивает предмет на другого через NPC или подобное - это имеет следующие стадии:
Примечания :
Сделки между игроками обрабатываются аналогично, с дополнительными правилами, предотвращающими мошенничество игроков с другими игроками, и дополнительным отслеживаемостью в случае необходимости отмены транзакции. Я слышал, что есть специальные журналы всех транзакций, которые хранятся в течение некоторого времени (для решения проблем, когда кто-то жалуется), я не знаю больше, как эта часть работает.
Иногда что-то идет не так, у этого есть два возможных результата:
В любом случае клиент знает об ошибке и регистрирует ее вместе со всем, что делал игрок. Ведение журнала на стороне клиента происходит постоянно. Затем при выходе из системы, если произошла ошибка, клиент отправляет журналы на сервер.
Эта игра не использует традиционное ежедневное или еженедельное время простоя обслуживания, которое есть у большинства MMORPG. Это плановое обслуживание часто используется для сброса счетчиков, таймеров, запуска процедур базы данных. Они также дают возможность поменять версии сервера для обновления.
источник
x:10,y:10,z:10
Комуx:11,y:11,z:11
, это должно быть сохранено в базе данных сразу? Что если игрок продолжает работать, это означает, что мы сохраняем его текущую позицию каждые 1 с или менее, а если есть тысячи игроков, это миллионы запросов к БД каждую секунду. Это как это работает?Оба подхода используются с MMORPG. Хранение всего в памяти и периодическая проверка наведения на диск кажется наиболее популярным вариантом, по крайней мере, для старых игр. Его преимущество в том, что он довольно прост в реализации и достаточно хорошо масштабируется, но сделать его надежным полностью зависит от разработчика. Базы данных SQL предоставляют свойства ACID, которые облегчают надежность, но в целом сложнее в реализации и могут иметь проблемы с масштабированием.
EVE Online - это пример MMO, где все хранится в базе данных SQL. Я думаю, что он достиг примерно 60000 одновременных пользователей, и ему пришлось выделять какое-то дорогостоящее оборудование для серверов баз данных на протяжении многих лет, чтобы не отставать от нагрузки. Однако EVE хранит намного больше данных на пользователя, чем большинство MMORPG, и имеет гораздо более частые и разнообразные транзакции. Свойства ACID базы данных позволяют поддерживать целостность всей массивной и сложной базы данных.
Например, рассмотрим случай, когда кто-то передает предмет другому игроку. База данных EVE гарантирует, что даже в случае сбоя или сбоя питания предмет попадет в инвентарь только одного игрока. То есть транзакция базы данных, которая удаляет элемент из инвентаря одного игрока и добавляет его в инвентарь другого игрока, является атомарной. Сделка либо полностью завершена, либо не происходит вообще. Вы не можете оказаться в состоянии, если предмет не существует ни в инвентаре игроков, ни в обоих.
MMORPG, которая хранит данные игрока в памяти и периодически проверяет, должна ли она сама реализовывать эту атомарность. Одним из способов сделать это будет одновременная проверка данных каждого игрока, гарантируя, что новая контрольная точка будет полностью зафиксирована на диске до того, как она будет считаться самой последней контрольной точкой. Игра также должна была бы гарантировать, что данные игрока не могут измениться во время проверки. С большим количеством активных игроков, задача становится делать все это, не вызывая задержки достаточно долго, чтобы игроки заметили.
Не стоит недооценивать, насколько важна последовательность. Когда вы разрабатываете свою игру, она очень часто падает. Вам не нужно отслеживать, почему предметы исчезают и / или дублируются, а не тогда, когда проблема связана с ошибкой, приводящей к аварийному завершению игры. Более того, когда ваша игра выйдет в эфир, она рухнет намного сильнее, чем вы ожидаете. Ваш сервер, который отлично работал при тестировании, неожиданно обнаружит многочисленные ошибки при полной нагрузке и действия игроков, о которых вы не ожидали.
Обратите внимание, что большинство MMORPG используют базы данных SQL для информации, связанной с учетной записью, даже если они не для реальных игровых данных. Еще более важным, чем сохранение состояния игры в согласованном состоянии, является поддержание согласованности состояния выставления счетов. В худшем случае, если база данных игры будет повреждена, вам придется восстанавливать базу данных из ежедневной резервной копии. В худшем случае, если база данных аккаунта будет повреждена, вы обанкротитесь из-за всех возвратных платежей.
Для вашего проекта вы можете пойти в любую сторону. 1000 одновременных пользователей, вероятно, не будут расширять границы возможностей, которые SQL-сервер может обрабатывать на обычных ПК в наши дни, но многое будет зависеть от характера транзакций. Если вы знакомы с SQL и проектированием реляционных баз данных, это может сработать для вас. Вы захотите свести к минимуму количество транзакций, насколько это возможно, для чего-то вроде текущих хитпоинтов игрока вы можете лишь периодически сохранять их в базе данных, поскольку подобная статистика не обязательно должна быть согласованной. (Хотя в PvP-игре они могут ...) Вообще не храните в базе данных такие вещи, как monster HP, в большинстве игр сохраняются только данные, относящиеся к игроку.
С другой стороны, если вы не являетесь мастером SQL, вам может показаться, что хранить все данные в памяти гораздо проще для надежной работы. Базы данных SQL упрощают согласованность и надежность, но не обеспечивают автоматическую работу. Плохо спроектированная база данных может работать плохо и приводить к несоответствиям. Транзакции не будут атомарными, если вы их не сделаете. Если вы не будете религиозно использовать параметризованные операторы, вы откроете себя для атак SQL-инъекций.
источник
Различные игры хранят вещи по-разному. Зачастую игровые компании создают какой-то способ сделать это, и большинство их игр используют один и тот же способ. Конечно, разные студии часто используют разные способы. SQL, безусловно, используется для игр, например, CCP (EVE) имеет (или, по крайней мере, имеет) сеть серверов SQL, я не уверен, как они это делают сейчас. Другие просто используют много файлов.
Может быть, начать с создания независимого «механизма брокера данных» для обработки различных транзакций с игровыми данными? Поскольку в любом случае вы просто тестируете, создайте механизм, который позволит вам не заботиться о хранилище с точки зрения самой игры. То есть сконцентрируйтесь на том, как из хост-приложения вы справитесь с этим.
Лично я думаю, что было бы очень полезно, если бы вы могли сменить магазин, не переписывая игру и самого брокера. Просто переключитесь на другой модуль с тем же интерфейсом, чтобы брокер мог с ним общаться.
Хранение данных само по себе, вероятно, не будет проблемой само по себе. Эффективная доставка данных в / из этого хранилища, между хостом и всеми клиентами, может быть сложнее. Должен ли я отправлять весь набор данных игрока, или если я разбиваю его на части, какую гранулярность я выбираю для разделения и т. Д. Какой из них более ресурсоемкий в какой ситуации и т. Д.
Одним из форматов отправки данных может быть XML. Таким образом, вы можете быть более динамичными в том, как вы можете разбить его на части. Один символ против нескольких символов, или один элемент против коллекции элементов и т. Д. Затем можно было бы либо «сохранить» XML как XML (в SQL), и / или заставить SQL распространять его более транзакционным способом из XML, чтобы как вы хотите данные на самом деле хранятся.
Другой способ - бинарный, более эффективный с точки зрения доставки, но в других ситуациях он может повлечь за собой большие затраты.
Имея 1000 клиентов, вы могли бы начать с простого хранения 10 МБ для каждого клиента и использовать только 10 ГБ оперативной памяти + добавить некоторую системную административную память для управления этими данными, скажем, еще один или два ГБ. Вы можете сохранить это в оперативной памяти на хосте, уже в структуре данных, готовой к использованию. И загружать / сохранять динамически, в зависимости от того, кто в сети, на разных частотах в зависимости от активности и т. Д.
Вы даже можете хранить информацию о каждом клиенте в отдельном файле и так далее.
источник
Держите * online * игроков в оперативной памяти и отправляйте их в базу данных (SQLite? MySQL?), Когда они выходят из системы. если вас беспокоит остановка ввода-вывода во время выхода из системы, присвойте каждому выходу свой собственный поток, не делайте этого в главном / игровом потоке (на самом деле я оставляю выделенный поток для каждого онлайн-игрока, это значительно упростило сетевой код) чем делать асинхронный сетевой подход)
источник