RE:NODE

Minecraft11 мин чтения

MySQL для плагинов и сетей Minecraft

Каким плагинам Minecraft нужен MySQL, как подключить LuckPerms, CoreProtect и другие, как рассчитать пул соединений и безопасно делить данные в сети серверов.

0 прочтений

Большинству плагинов Minecraft MySQL не нужен. Они хранят данные в YAML-файлах, SQLite или H2 внутри своей папки, и на одном сервере это нормально. Настоящий сервер баз данных - MySQL, MariaDB или PostgreSQL, если плагин его поддерживает, - нужен в двух случаях: когда несколько серверов должны видеть одни и те же данные (права, баны, экономика по всей сети) или когда плагин пишет так много, что локальная файловая база становится узким местом, а на практике это означает CoreProtect на загруженном сервере. Всё остальное может оставаться там, где лежит.

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

Когда база данных оправдана, а когда нет#

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

Локальное хранилище - YAML, SQLite, H2 - лежит на диске самого сервера, и пользоваться им может только процесс этого сервера. Оно не требует настройки, ничего не нужно держать запущенным, и в резервную копию оно попадает вместе с остальной папкой сервера. Его ограничения - конкурентный доступ (SQLite и H2 выполняют записи по очереди) и досягаемость (второй сервер его не видит).

Сервер баз данных - это отдельный процесс, к которому обращаются по сети. К нему одновременно может подключаться сколько угодно серверов Minecraft, он правильно обрабатывает параллельные записи, и к нему можно делать запросы извне игры - например, с сайта, который показывает списки банов или статистику игроков. Цена - ещё одна вещь, которая должна работать, ещё один набор учётных данных, ещё одна вещь для резервного копирования и несколько миллисекунд задержки на каждом запросе.

СитуацияЧто использовать
Один сервер, обычные плагиныЛокальное хранилище. Ничего не делайте
Один сервер, CoreProtect с интенсивным логированиемСервер баз данных для CoreProtect
Два сервера или больше с общими правамиСервер баз данных для LuckPerms
Баны на всю сетьСервер баз данных для плагина банов
Сайт, читающий данные плагиновСервер баз данных
Общая экономика между серверамиСервер баз данных, с осторожностью (см. ниже)

Ловушка - переносить всё в MySQL, потому что в каком-то гайде написали, что так «лучше». Плагин, который хранит двадцать килобайт данных вроде конфига и читает их один раз при запуске, ничего не выигрывает, зато теперь зависит от того, поднята ли база, прежде чем сервер сможет стартовать.

Плагины с поддержкой базы данных и что они хранят#

Вот самые распространённые. Точные ключи для вашей версии лучше всего смотреть в вики самого плагина; ниже приведены актуальные варианты.

ПлагинЛокально по умолчаниюВарианты базы данныхЗачем переносить
LuckPermsH2MySQL, MariaDB, PostgreSQL, MongoDBОбщие права на нескольких серверах
CoreProtectSQLiteMySQLОбъём записи на загруженных серверах
LiteBansH2MySQL, MariaDB, PostgreSQLБаны на всю сеть, веб-просмотр
Plan (Player Analytics)SQLiteMySQLСведение статистики с нескольких серверов
DynmapФайлыSQLite, MySQLТайлы карты в базе вместо файлов
BlueMapФайлыSQL-базы данныхТо же самое для BlueMap
mcMMOПлоский файлMySQLОбщие навыки на нескольких серверах

Некоторые плагины экономики тоже умеют работать с базой; EssentialsX не умеет и хранит балансы в YAML-файлах каждого игрока - альтернативы с базой данных разобраны в руководстве по экономике.

Плагины карт - особый случай. Хранить тайлы в базе можно, но выигрыша это почти никогда не даёт: большой и в основном неизменный набор картинок переезжает в базу, которую потом нужно бэкапить и обслуживать. Держите тайлы карты на диске, если у вас нет конкретной причины поступить иначе, - компромисс объяснён в статье Dynmap и BlueMap.

Создание базы и пользователя#

Какой бы движок вы ни использовали, схема одна и та же: одна база (или один префикс таблиц) на каждое назначение плагина, один пользователь с правами только на эту базу и сильный сгенерированный пароль.

На сервере баз данных, которым вы управляете сами, в MySQL или MariaDB:

sql
CREATE DATABASE mc_luckperms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;CREATE USER 'mc_luckperms'@'%' IDENTIFIED BY 'a-long-generated-password';GRANT ALL PRIVILEGES ON mc_luckperms.* TO 'mc_luckperms'@'%';FLUSH PRIVILEGES;

utf8mb4 важен. Игроки вставляют эмодзи и нелатинские символы в названия домов и магазинов, в ники и в чат; старая кодировка utf8 в MySQL хранит только три байта на символ и ломается на всём, что выходит за базовую плоскость. Большинство современных плагинов создают свои таблицы в utf8mb4, если это позволяет кодировка базы по умолчанию.

'%' разрешает подключения с любого адреса. Если база и серверы Minecraft находятся в частной сети, ограничьте доступ её диапазоном. Если база доступна из интернета, сильный пароль - единственное, что стоит между ней и каждым сканером на планете, - см. чек-лист безопасности баз данных.

У хостера с панелью эти команды обычно выполнять самому не нужно. В RE:NODE в каждый тариф Minecraft входит слот базы данных: вы создаёте её в панели, и она сразу идёт со сгенерированными хостом, пользователем и паролем, плюс кнопка «Open in phpMyAdmin», которая пускает вас по одноразовому токену, чтобы смотреть таблицы и выполнять запросы. Именно эти три значения вы и вставляете в конфиг плагина.

Подключение LuckPerms#

LuckPerms большинство переносит первым, и его конфиг - хороший образец для остальных. В plugins/LuckPerms/config.yml:

plugins/LuckPerms/config.yml
storage-method: mysqldata:  address: db.example.com:3306  database: mc_luckperms  username: mc_luckperms  password: 'a-long-generated-password'  pool-settings:    maximum-pool-size: 10    minimum-idle: 10    maximum-lifetime: 1800000    keepalive-time: 0    connection-timeout: 5000  table-prefix: 'luckperms_'messaging-service: auto

Строки, которые имеют значение:

  • storage-method для удалённого хранилища принимает mysql, mariadb, postgresql или mongodb. Если сервер на MariaDB, используйте mariadb: драйверы немного различаются.
  • address включает порт. Если его не указать, подразумевается порт движка по умолчанию.
  • messaging-service: auto заставляет LuckPerms рассылать изменения между серверами. При SQL-хранилище и без Redis он переходит на периодический опрос базы. Именно благодаря этому /lp user Steve parent add vip на одном сервере срабатывает на остальных без перезапуска.

Чтобы перенести существующие права, а не начинать с нуля, выполните /lp export backup на старом хранилище, поменяйте конфиг, перезапустите сервер и затем выполните /lp import backup. Экспорт попадает в папку LuckPerms в виде сжатого файла; в любом случае сохраните его как резервную копию. Когда с хранилищем разобрались, группы и контексты описаны в руководстве по LuckPerms.

Подключение CoreProtect#

CoreProtect записывает каждое изменение блока, каждую операцию с контейнером и каждую строку чата. На загруженном сервере выживания это миллионы строк в неделю, и SQLite начинает не справляться: поиск занимает секунды, а очередь, которая пишет логи, может начать отставать. Вот тогда MySQL и оправдывает себя.

plugins/CoreProtect/config.yml
use-mysql: truetable-prefix: co_mysql-host: db.example.commysql-port: 3306mysql-database: mc_coreprotectmysql-username: mc_coreprotectmysql-password: 'a-long-generated-password'

Сам CoreProtect не переносит данные из SQLite в MySQL. После переключения начинается новый, пустой лог; старый database.db остаётся в папке плагина. Либо смиритесь с чистого листа (и подержите старый файл несколько недель, чтобы при необходимости временно переключиться обратно и поискать в нём), либо воспользуйтесь инструментом миграции, которому доверяете, и сначала проверьте его на копии.

Продумайте объём. CoreProtect - плагин, который скорее всех заполнит базу. С самого начала заведите привычку чистить её через purge - /co purge t:30d удаляет данные старше тридцати дней - и поставьте это по расписанию, потому что лог блоков трёхлетней давности редко стоит места на диске. Не делите таблицы CoreProtect между серверами: координаты и названия миров разных серверов перемешаются. Дайте каждому серверу свою базу или свой table-prefix.

Пулы соединений: сколько соединений вы на самом деле открываете#

Почти каждый Java-плагин, работающий с базой, использует пул соединений, обычно HikariCP. Пул открывает фиксированное число соединений при запуске и держит их открытыми, чтобы запросы не тратили время на подключение. Для плагина это эффективно, а для базы - легко недооценить.

Арифметика такая: плагины умножить на серверы умножить на размер пула:

КонфигурацияРасчётСоединений
Один сервер, пул LuckPerms по умолчанию1 x 1010
Один сервер, LuckPerms + CoreProtect + LiteBans10 + несколько + 10около 25
Сеть из четырёх серверов, те же три плагина4 x 25около 100
Та же сеть плюс LuckPerms на прокси100 + 10около 110

По умолчанию max_connections в MySQL равен 151, а управляемые или общие тарифы баз данных часто разрешают меньше. Небольшая сеть может упереться в лимит так, что никто этого не заметит до перезапуска, когда все серверы разом пытаются открыть свои пулы и последний получает Too many connections.

Для нагрузки Minecraft небольших пулов достаточно. Пула LuckPerms на 3-5 соединений на сервер с запасом хватает сети до нескольких сотен игроков: он в основном кеширует данные в памяти и обращается к базе при входе и при изменениях. Уменьшайте maximum-pool-size и minimum-idle вместе. В статье пулы соединений и лимиты объясняется, почему пул побольше часто работает медленнее, а не быстрее.

Общие данные в сети серверов#

Чаще всего сюда приходят из-за сети за прокси: лобби, сервер выживания и сервер мини-игр за Velocity. Что делить, а что нет:

праваVelocityLuckPermsЛоббиLuckPerms, LiteBansВыживаниеLuckPerms, CoreProtectМини-игрыLuckPerms, статистикаСервер БДсхема на каждую задачу
Один сервер БД за небольшой сетью

Делите права (LuckPerms, одна база и один префикс везде, включая прокси), баны и муты (сетевой режим плагина банов) и всё, что должен показывать сайт.

Не делите логи блоков (CoreProtect, у каждого сервера свои), данные, привязанные к миру, вроде приватов и регионов (они ссылаются на координаты в одном мире), и данные плагинов, в документации которых явно не сказано, что несколько серверов могут писать одновременно. Два сервера, пишущие в таблицы, которые плагин считает своими, дают тихое повреждение данных, а не ошибки.

Делите с осторожностью: балансы экономики и инвентари. Общий баланс означает, что покупка на одном сервере и платёж на другом могут столкнуться; плагин, написанный для сетей, решает это блокировками, а плагин, который просто поддерживает MySQL, может и не решать. Плагины синхронизации инвентаря могут дублировать предметы, если сервер падает посреди передачи. Многие сети специально держат отдельную экономику для каждого режима именно по этой причине.

База и серверы должны находиться рядом. Каждый запрос платит за полный путь туда и обратно, а плагины, которые делают запросы в основном потоке (плохо написанные так и делают), останавливают тик на это время. База на той же машине или в той же сети обходится гораздо меньше чем в миллисекунду; база на другом континенте - в 100 мс на запрос, а это два полных тика.

PostgreSQL или MongoDB вместо MySQL#

MySQL и MariaDB - наименьший общий знаменатель: на них говорит почти каждый плагин с поддержкой баз данных. PostgreSQL и MongoDB поддерживает меньше плагинов, но самые важные для сетей часто поддерживают: LuckPerms работает с обоими, LiteBans - с PostgreSQL. Если вы всё равно поднимаете отдельную базу для сети, проверьте каждый нужный плагин до выбора движка.

Хостинг баз данных в RE:NODE предлагает PostgreSQL и MongoDB отдельными серверами со сгенерированным паролем суперпользователя, доступными по собственному хосту и порту тарифа, - разумное место для LuckPerms и плагина банов в сети, при условии что каждый нужный плагин поддерживает этот движок. Для плагинов, которые умеют только MySQL, проще выбрать слот базы данных, входящий в игровой тариф. Если вы не работали ни с одним из них, разница разобрана в статье Postgres или MongoDB.

Резервные копии и обслуживание#

База данных плагинов теперь часть вашего мира. Восстановить папку мира за вторник, оставив права и баны на пятнице, - несоответствие, которое вы заметите. Бэкапьте и то и другое по одному расписанию, а также перед каждым обновлением плагина, в changelog которого упомянута «database migration».

bash
$ mysqldump --single-transaction --default-character-set=utf8mb4 \    -h db.example.com -u mc_luckperms -p mc_luckperms > luckperms.sql

--single-transaction снимает согласованный снимок таблиц InnoDB без их блокировки, поэтому серверы продолжают работать во время дампа. У CoreProtect дамп может быть большим; сначала удалите старые данные, и дамп уменьшится вместе с ними. Расписания и проверка описаны в статье резервные копии и восстановление баз данных.

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

Ошибки подключения#

`Communications link failure`. Плагин вообще не смог достучаться до базы. Неверный хост или порт, база не работает, или мешает файрвол. Прежде чем винить плагин, проверьте подключение любым MySQL-клиентом с той же машины.

`Access denied for user 'x'@'y'`. Неверный пароль, или пользователь существует, но с этого хоста ему подключаться нельзя. 'y' в сообщении - адрес, который увидела база; сравните его с хостовой частью созданного вами пользователя.

`Unknown database`. Базы с именем из конфига не существует, или регистр букв другой. В Linux имена баз MySQL чувствительны к регистру.

`Too many connections`. Та самая арифметика пулов выше. Уменьшите пулы или найдите плагин, который не закрывает соединения, наблюдая за списком процессов, пока сервер работает.

`Public Key Retrieval is not allowed`. Новый сервер MySQL с аутентификацией caching_sha2_password и драйвер, который отказывается получать ключ по незашифрованному соединению. Либо подключайтесь через TLS, либо (в частной сети) добавьте allowPublicKeyRetrieval=true в параметры подключения плагина, если он позволяет их задавать.

Сервер в случайные моменты замирает на секунду. Плагин выполняет запросы в основном потоке к медленной или далёкой базе. spark покажет в профиле и плагин, и вызов JDBC.

FAQ#

MySQL быстрее SQLite для плагинов Minecraft?

Для одного сервера с лёгкой нагрузкой обычно нет: у SQLite на быстром локальном диске нет сетевой задержки. MySQL выигрывает при интенсивных параллельных записях, как у CoreProtect на загруженном сервере, и это единственный вариант, когда несколько серверов делят данные.

Могут ли все серверы моей сети использовать одну базу?

Один сервер баз данных - могут. Делить ли таблицы, зависит от плагина: LuckPerms и плагины банов для этого созданы, логгеры блоков и плагины приватов - нет. Если сомневаетесь, дайте каждому серверу свой префикс таблиц.

Что будет, если база упадёт?

Плагины, которым она нужна, перестанут работать: LuckPerms может отказывать во входе или перейти на кешированные данные, CoreProtect ставит записи в очередь, а потом выдаёт ошибки. Ваших миров это не касается. Запускайте сначала базу, а потом игровые серверы, и не размещайте базу там, где она менее надёжна, чем зависящие от неё серверы.

Что выбрать - MariaDB или MySQL?

Для плагинов Minecraft они взаимозаменяемы. Если плагин предлагает отдельный вариант mariadb, используйте его с MariaDB, потому что он выбирает подходящий драйвер.

Насколько большой станет база?

LuckPerms и плагины банов остаются маленькими, обычно несколько мегабайт даже в больших сетях. Исключение - CoreProtect: на загруженном сервере он может дорасти до гигабайтов за несколько месяцев. Удаляйте старые логи по расписанию, и размер останется предсказуемым.


Комментарии

Полностью анонимно: без аккаунта, без почты, без cookie. Мы храним имя, которое вы ввели, текст и время - больше ничего. Количество ссылок ограничено, разметка не отображается.

0/2000