Привет, Хабр!
Сегодня мы рассмотрим Resource Groups в MySQL — и перестанем жить на одной CPU.
Resource Groups — это контроль над CPU прямо из SQL. Вы создаёте логическую группу, говорите «эта группа может использовать только 2 CPU и работать на низком приоритете», и назначаете туда тяжелые, но второстепенные задачи. Всё. Дальше MySQL сам всё регулирует.
Прежде чем начать
Сначала проверим, включена ли вообще эта фича:
SHOW VARIABLES LIKE 'resource_group_enabled';
Если ON — отлично. Если OFF, скорее всего:
-
У вас macOS (там это не работает в принципе).
-
Или у вас включён thread pool (он конфликтует).
-
Или вы сидите на древней версии MySQL.
Если всё норм, едем дальше.
По дефолту есть две группы
SELECT * FROM INFORMATION_SCHEMA.RESOURCE_GROUPS\G
Получите вот такое:
RESOURCE_GROUP_NAME: USR_default RESOURCE_GROUP_TYPE: USER VCPU_IDS: 0-3 THREAD_PRIORITY: 0
То есть, если вы никогда ничего не настраивали, весь ваш код, все ваши запросы, API, ETL, BI, всё работает в одном тазике USR_default. Без приоритета и без ограничений.
Наведём порядок
Допустим, у нас есть ETL-запросы или отчёты из Metabase, которым ни к чему мешать пользователям. Хотим их ограничить по CPU и поставить в конец очереди.
Создаём:
CREATE RESOURCE GROUP etl_group TYPE = USER VCPU = 2-3 THREAD_PRIORITY = 15;
Переводим на русский:
-
VCPU = 2-3— используем только два ядра. -
THREAD_PRIORITY = 15— низкий приоритет (где 0 — норм, 19 — спи спокойно, малыш).
Назначаем сессию в группу
Узнали CONNECTION_ID() и назначаем поток:
SET RESOURCE GROUP etl_group FOR 123;
Или если хотим назначить себе прямо сейчас:
SET RESOURCE GROUP etl_group;
Теперь SQL будет отрабатывать их не мешая никому.
Но можно и точечно — только один запрос
SELECT /*+ RESOURCE_GROUP(etl_group) */ COUNT(*) FROM big_table;
Всё, что внутри запроса — будет выполнено с ограничениями группы.
Проверим, кто куда попал
SELECT THREAD_ID, RESOURCE_GROUP_NAME FROM performance_schema.threads WHERE PROCESSLIST_ID = CONNECTION_ID();
Если всё ок — будете видеть etl_group как текущую группу.
Как менять группу на ходу
Ночью можно дать больше приоритета:
ALTER RESOURCE GROUP etl_group VCPU = 0-3, THREAD_PRIORITY = 5;
Днём снова поджали:
ALTER RESOURCE GROUP etl_group VCPU = 2, THREAD_PRIORITY = 18;
А если не помогает — значит нет прав
Да, нужны привилегии. Вот как их выдать:
GRANT RESOURCE_GROUP_ADMIN ON *.* TO 'my_admin'@'%';
Тогда можно будет создавать и менять группы. А если просто использовать:
GRANT RESOURCE_GROUP_USER ON *.* TO 'etl_worker'@'%';
Некоторые проблемы
Список всех проблем:
-
macOS не поддерживается вообще.
-
FreeBSD и Solaris игнорируют приоритеты. Всё всегда на
0. -
Linux требует
CAP_SYS_NICE. Без этого приоритеты игнорируются. Включить:
sudo setcap cap_sys_nice+ep /usr/sbin/mysqld
Лучше — через systemd:
sudo systemctl edit mysql
Добавьте:
[Service] AmbientCapabilities=CAP_SYS_NICE
-
Thread Pool plugin ломает всё. Его надо отключить.
Три кейса использования
BI-отчёты на Metabase не душат REST-API
На одном сервере живут фронтовое API (latency < 100 мс) и Metabase, который в пик дня гоняет SELECT … GROUP BY на десятки секунд. Фронт-энд периодически замирает.
Решение
-- создаём группу под BI CREATE RESOURCE GROUP bi_low TYPE = USER VCPU = 3 -- одно «спокойное» ядро THREAD_PRIORITY = 18; -- почти самый низкий приоритет
В настройках подключения Metabase добавляем startup-query:
SET RESOURCE GROUP bi_low;
Теперь все BI-запросы ограничены одним ядром и низким приоритетом — API обслуживается без скачков latencies.
Ночные ETL-джобы Parallel Ingest против дневного OLTP
Cron в 02:00 поднимает Java-процесс, который заливает данные пачками INSERT … ON DUPLICATE KEY UPDATE. Днём всё ок, но если бэкап сместился и ETL стартовал в рабочий час — база становится резиновой.
Решение
-- заводим группу для ETL CREATE RESOURCE GROUP etl_batch TYPE = USER VCPU = 1-2 -- два ядра из восьми THREAD_PRIORITY = 10;
Java-процессу в строку подключения пишем:
jdbc:mysql://db:3306/app?sessionVariables=resource_group=etl_batch
Днём ETL не вылазит за выделенные CPU, ночью при желании можно поднять приоритет:
ALTER RESOURCE GROUP etl_batch VCPU = 0-3 THREAD_PRIORITY = 2;
Крутить ad-hoc-запросы
Иногда нужно быстро проверить гипотезу, и кто-то запускает EXPLAIN ANALYZE на таблицу в 200 М строк. Если соединение открыто под обычной учёткой, запрос лезет в ту же очередь, что и боевые платежи.
Решение
-- создаём песочницу для ручных запросов CREATE RESOURCE GROUP dev_lab TYPE = USER VCPU = 2-3 THREAD_PRIORITY = 16;
Даем разработчикам отдельный логин:
GRANT RESOURCE_GROUP_USER ON *.* TO 'dev'@'%'; GRANT USAGE ON *.* TO 'dev'@'%'; GRANT SELECT, EXPLAIN ON prod_db.* TO 'dev'@'%';
И в .my.cnf этого логина пишем:
[client] user = dev password = **** init_command = "SET RESOURCE GROUP dev_lab"
Итоги
Resource Groups — полезная фича MySQL: закрепили ядра, задали приоритеты, и тяжёлые BI- или ETL-потоки больше не топят прод; настройка занимает минуты, а выигрыш — стабильные миллисекунды отклика в пиковые часы. Если вам уже довелось приручать запросы через свои группы, поделитесь в комментарих вашим опытом — коллективный опыт всегда мощнее любой официальной документации.
Освоить MS SQL Server на профессиональном уровне и расширить свои возможности в IT можно на онлайн-курсе «MS SQL Server Developer».
Если интересно узнать свой уровень знаний для поступления на курс, пройдите вступительное тестирование.
ссылка на оригинал статьи https://habr.com/ru/articles/932060/
Добавить комментарий