Поскольку кластеров много, а на управление медленными запросами и обеспечение приоритета коротких запросов не хочется тратить много времени, был разработан вспомогательный сервис для контроля медленных запросов. Ниже — как это реализовано и используется сейчас.
Фон: перехват медленных запросов
Контроль медленных запросов (Часть первая. Пояснение)
(01). Проектирование записи данных в таблицу
①. На уровне данных: создать таблицу и спроектировать запись событий перехвата в БД.
②. На уровне программы: использовать stream load для накопления и пакетной загрузки данных.
③. На уровне Feishu: подготовить шаблоны сообщений.
④. На уровне мониторинга: визуализация в виде линейных графиков в Grafana.
⑤. На уровне электронной почты: подготовить шаблоны писем.

(02). Проектирование режимов перехвата
Краткое описание логики перехвата:
-
①. Напоминание о медленном запросе через 10 минут (пояснение: если с момента отправки запроса прошло более 10 минут — отправить уведомление).

-
②. Принудительное завершение через 30 минут (kill) (пояснение: если с момента отправки запроса прошло более 30 минут — завершить запрос).

-
③. Принудительное завершение при full table scan на уровне 10^8 строк (пояснение: если запрос относится к типу full table scan и объём достигает сотен миллионов строк — завершить).

-
④. Принудительное завершение при сканировании 10^10 строк (пояснение: если количество сканируемых строк достигает 10 миллиардов — завершить).

-
⑤. Принудительное завершение при сканировании объёма в TB (пояснение: если объём сканируемых байтов достигает уровня TB — завершить).

-
⑥. Принудительное завершение при нарушающих параметрах (пояснение: если запрос отправлен с нарушающими параметрами — завершить, например, query_mem_limit=999999999999999999).

-
⑦. Предупреждение о конкуренции в очереди (пояснение: если конкурентность/QPS достигает 100 — отправить напоминание).

⑧. Мягкая защита по белому списку (пояснение: для некоторых ключевых пользователей действует защита, задаётся в таблице конфигурации).
-
⑨. Принудительное завершение при нарушениях в CATALOG (пояснение: если запрос выполняет INSERT во внутреннюю таблицу из hive catalog и объём превышает 100 млн строк — завершить).

-
⑩. Принудительное завершение при потреблении памяти на уровне GB (пояснение: если после передачи запроса на BE потребление памяти превышает 200 GB — завершить).


(03). Проектирование координационного фреймворка
Источники данных:
-
①. Режим процесса (data collection): получать актуальные SQL из
show processlist.

②. Режим очереди (data collection): получать актуальные SQL по адресу
http://FE:8030/system?path=//current_queries.
(04). Разработка базовых функций
Аналитические возможности:
-
①. Анализ execution plan.

-
②. Парсинг для извлечения имён таблиц.

-
③. Классификация типа сканирования.

-
④. Расчёт точного коэффициента перекрытия (overlap coefficient).

-
⑤. Идентификация очередей процессов.

-
⑥. Отображение распределения реплик.

⑦. Анализ сортировки и разбиения на бакеты (bucketing).
-
⑧. Формирование анализа причин.

-
⑨. Генерация справочных материалов.

⑩. Персональная доставка оповещений (через бота приложения Feishu, отправка уведомлений соответствующему пользователю AD).
(05). Разработка расширенных функций
Из-за наличия двух типов учётных записей — native и AD — владельцы (owner) могут различаться. Ответственный по аккаунту определяется из разных источников; при срабатывании оповещения ответственному направляется письмо с требованием оптимизировать запрос.
①. По локальному (native) аккаунту получать связанный ID, английное имя и список подчинённых.
②. По LDAP/AD-аккаунту получать связанный ID и английное имя.
(06). Модуль отправки оповещений
После анализа и фиксации события оповещения доставляются в разные каналы (Feishu + корпоративная почта):
①. В зависимости от кластера — в разные групповые чаты.
②. В зависимости от аккаунта — в разные групповые чаты.
③. В зависимости от аккаунта — в личный Feishu (через бота приложения Feishu).
④. В зависимости от аккаунта — на личную почту.
⑤. В зависимости от аккаунта — на личную почту и с копией его подчинённым.
(07). Этап отладки и запуска
Исправления и улучшения (не критичные):
①. Исправлен выход за границы массива.
②. Добавлено распознавание пустых партиций.
③. Добавлено получение информации об очередях через API.
④. Переход к этапу оптимизации.
⑤. Исправлены аномалии при распределении оповещений.
…
Контроль медленных запросов (Часть вторая. Конфигурация)
Описание таблиц данных (три таблицы конфигурации)
Стандартная таблица конфигурации программы — используется для чтения настроек при старте (тип мониторинга, режимы перехвата и т. п.)
CREATE TABLE `sr_slow_query_config` (
`slow_query_time` int NOT NULL DEFAULT '600' COMMENT 'Время тайм-аута для уведомления о медленном запросе, в секундах.',
`slow_query_ktime` int NOT NULL DEFAULT '1500' COMMENT 'Время до принудительного завершения (kill) медленного запроса, в секундах.',
`slow_query_concurrencylimit` int NOT NULL DEFAULT '80' COMMENT 'Порог конкурентности для медленных запросов (например, если число параллельных запросов превышает это значение — оповещать), целое число.',
`slow_query_version` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'Версия программы.',
`slow_query_focususer` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'Белый список защищённых пользователей; значения через запятую.',
`slow_query_proxy_feishu` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'Прокси-адрес для доступа к Feishu (при отправке сообщений может требоваться прокси).',
`slow_query_email_host` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'Корпоративная почта: адрес сервера, host:port.',
`slow_query_email_from` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'Корпоративная почта: адрес отправителя.',
`slow_query_email_to` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'Корпоративная почта: адреса получателей, через запятую.',
`slow_query_email_cc` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'Корпоративная почта: адреса для копии (CC), через запятую.',
`slow_query_email_bc` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'Корпоративная почта: адреса для скрытой копии (BCC), через запятую.',
`slow_query_email_suffix` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'Суффикс корпоративной почты, @xxxxx.com.',
`slow_query_email_reference_material` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'Справочные материалы в письме; поддерживается HTML, значения через запятую.',
`slow_query_frontend_avgs` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT 'parallel_fragment_exec_instance_num=15,query_mem_limit=274877906944,load_mem_limit=274877906944,exec_mem_limit=274877906944' COMMENT 'Параметры для перехвата медленных запросов: key=value,... можно несколько.',
`slow_query_frontend_fullscan_num` int DEFAULT '200000000' COMMENT 'Максимальное число строк для перехвата full table scan; по умолчанию 200 млн.',
`slow_query_frontend_insert_catalog_scanrow` int DEFAULT '100000000' COMMENT 'Перехват при сканировании из CATALOG объёма на уровне 10^8 + INSERT TABLE FROM CATALOG.',
`slow_query_frontend_memoryusage` int DEFAULT '200' COMMENT 'Порог по памяти: потребление одним BE свыше 200 GB.',
`slow_query_frontend_scanrows` bigint DEFAULT '10000000000' COMMENT 'Перехват при сканировании 10^10+ строк.',
`slow_query_frontend_scanbytes` int DEFAULT '5' COMMENT 'Перехват при сканировании объёма уровня TB+.',
`slow_query_data_registration_username` varchar(100) DEFAULT NULL COMMENT 'Имя пользователя для записи сведений о медленных запросах в таблицу.',
`slow_query_data_registration_password` varchar(500) DEFAULT NULL COMMENT 'Пароль для записи сведений о медленных запросах в таблицу.',
`slow_query_data_registration_table` varchar(500) DEFAULT NULL COMMENT 'Имя таблицы для записи сведений о медленных запросах.',
`slow_query_data_registration_host` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'Хост для записи сведений о медленных запросах (FE IP).',
`slow_query_data_registration_port` int DEFAULT '8030' COMMENT 'Порт для записи сведений о медленных запросах (используется stream load, по умолчанию 8030).',
`slow_query_resource_group_cpu_core_limit` int DEFAULT '10' COMMENT 'Изоляция ресурсов (resource group): лимит CPU.',
`slow_query_resource_group_mem_limit` int DEFAULT '50' COMMENT 'Изоляция ресурсов (resource group): лимит памяти (в процентах/условных единицах политики).',
`slow_query_resource_group_concurrency_limit` int DEFAULT '3' COMMENT 'Изоляция ресурсов (resource group): лимит конкурентности.',
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Время обновления.',
`slow_query_grafana` varchar(200) DEFAULT NULL COMMENT 'Адрес Prometheus; поддерживается отправка записей в Prometheus.'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
Таблица конфигурации бота Feishu — для хранения ключей ботов и привязки к меткам кластеров
CREATE TABLE `sr_slow_query_robot` (
`type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'Тип бота: global, cluster, user.',
`key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'Метка уведомлений по кластеру.',
`robot` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'Ключ бота Feishu.',
`status` int NOT NULL DEFAULT '0' COMMENT 'Переключатель.',
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Время обновления.'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Бот для доставки оповещений о медленных запросах';
Таблица информации о подключениях кластеров — аккаунт, пароль, хост, порт, адрес manager
CREATE TABLE `sr_slow_query_manager` (
`app` varchar(100) NOT NULL COMMENT 'Имя кластера (на английском).',
`feip` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'Адрес подключения к кластеру (обязателен): F5, VIP, CLB, FE.',
`user` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'Учётная запись для входа в кластер (обязательна); рекомендуется администратор.',
`password` varchar(500) NOT NULL COMMENT 'Пароль для входа (обязателен).',
`feport` int NOT NULL DEFAULT '9030' COMMENT 'Порт для входа в кластер, по умолчанию 9030.',
`address` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'MANAGER-адрес; если указан, запускается периодическая проверка срока действия LICENSE (Enterprise).',
`expire` int DEFAULT '30' COMMENT 'Порог напоминания об истечении LICENSE (Enterprise), в днях.',
`status` int NOT NULL DEFAULT '0' COMMENT 'Переключатель проверки LICENSE (Enterprise): 0 — off, 1 — on.',
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Время обновления.'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='Конфигурация входа в StarRocks и manager-адрес (периодическая проверка license)';
Контроль медленных запросов (Часть третья. Конфигурационный файл)
Программе требуется конфигурационный файл (написана на Golang), starrocks.yaml.
configdb:
Host: 127.0.0.1 # Адрес MySQL для таблиц конфигурации
Port: 3306 # Порт MySQL для таблиц конфигурации
User: root # Учётная запись MySQL
Pass: xxxxxxxxxx # Пароль MySQL
Schema:
App: chengken.sr_slow_query_config # Стандартная таблица конфигурации
Connect: chengken.sr_slow_query_manager # Таблица подключения кластера
Robot: chengken.sr_slow_query_robot # Таблица конфигурации бота Feishu
logger:
LogPath: /u/xxxx # Путь к журналам
LogLevel: "info"
MaxSize: 0
MaxBackups: 0
MaxAge: 0
Compress: false
JsonFormat: false
ShowLine: true
LogInConsole: true
Контроль медленных запросов (Часть четвёртая. Инициализация)
При первом запуске программа проверяет соединение с базой данных и наличие созданных таблиц конфигурации. Если таблицы не созданы заранее, запускается интерактивный режим, который пошагово помогает их создать.

Контроль медленных запросов (Часть пятая. Режим постоянной работы)
После успешной инициализации программа переходит в постоянный режим (daemon/служба) и по умолчанию раз в 2 минуты сканирует отправленные SQL-запросы. Запросы, по которым уже было отправлено оповещение, помещаются в кэш; повторное напоминание отправляется только после истечения срока жизни кэша. Время жизни кэша связано с параметром slow_query_time в стандартной таблице конфигурации.
