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

Фон: перехват медленных запросов

Контроль медленных запросов (Часть первая. Пояснение)

(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.

  • ④. Переход к этапу оптимизации.

  • ⑤. Исправлены аномалии при распределении оповещений.


Контроль медленных запросов (Часть вторая. Конфигурация)

Описание таблиц данных (три таблицы конфигурации)

  1. Стандартная таблица конфигурации программы — используется для чтения настроек при старте (тип мониторинга, режимы перехвата и т. п.)

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;
  1. Таблица конфигурации бота 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='Бот для доставки оповещений о медленных запросах';
  1. Таблица информации о подключениях кластеров — аккаунт, пароль, хост, порт, адрес 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 в стандартной таблице конфигурации.