Перейти к содержимому
Последнее обновление

Прерывание запросов: руководство по настройке SQL Block Rule и Workload Policy

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

Doris предоставляет два механизма прерывания, которые действуют на разных этапах жизненного цикла запроса:

КритерийSQL Block Rule (прерывание на этапе планирования)Workload Policy (прерывание во время выполнения)
Этап срабатыванияЭтап планирования запроса: перехват до начала выполненияЭтап выполнения запроса: прерывание во время работы
Основание для срабатыванияОценочный объём сканирования, сопоставление с шаблонами SQLМетрики в реальном времени: фактическое время выполнения, использование памяти, объём сканирования
ТочностьИспользует оценку стоимости, возможны ложные срабатыванияИспользует мониторинг в реальном времени, более высокая точность
Сценарий использованияБлокировка известных опасных шаблонов SQL и полного сканирования таблицПрерывание выполняющихся запросов, которые превышают ожидаемые показатели
Поддерживаемые операторыЛюбые операторы (DDL, DML)select, insert into select, stream load, routine load

SQL Block Rule​

SQL Block Rule перехватывает операторы, соответствующие заданным шаблонам, на этапе планирования, не допуская их выполнения. Обычно этот механизм настраивают администраторы баз данных для предотвращения заведомо рискованных операций, таких как полное сканирование таблиц и вызовы опасных функций.

Свойства правила​

Каждое правило определяется следующими свойствами, которые задают его поведение и область действия:

СвойствоОписаниеЗначение
sqlРегулярное выражение для сопоставления с текстом запросаСтрока с регулярным выражением Java
sqlHashХеш-значение для сопоставления с запросомСтрока с хеш-значением SQL
cardinalityМаксимальное допустимое количество сканируемых строкПоложительное целое число
partition_numМаксимальное допустимое количество сканируемых партицийПоложительное целое число
tablet_numМаксимальное допустимое количество сканируемых tabletПоложительное целое число
globalЯвляется ли правило глобальным"true" (глобальное) / "false" (действует только для пользователей, к которым привязано правило)
enableВключено ли правило"true" / "false"

Сценарии использования и примеры​

Сценарий 1: ограничение количества сканируемых строк​

Проблема: операции полного сканирования таблицы, такие как SELECT * FROM t, потребляют значительные ресурсы IO и CPU на BE.

Решение: задайте верхний предел количества строк, сканируемых в одной таблице. Запросы, превышающие этот порог, блокируются.

CREATE SQL_BLOCK_RULE rule_card 
PROPERTIES
(
"cardinality" = "1000",
"global" = "true",
"enable" = "true"
);

Если при сканировании одной таблицы количество строк превышает 1000, запрос отклоняется.

Сценарий 2: ограничение количества сканируемых партиций​

Проблема: сканирование слишком большого количества партиций значительно увеличивает потребление ресурсов CPU на BE. При запросах к внешним таблицам также возрастают накладные расходы на сетевое взаимодействие и получение метаданных. Обычно это связано с отсутствующими или неправильно заданными условиями фильтрации по партициям.

Решение: задайте максимальное количество партиций, которое может сканировать один запрос.

CREATE SQL_BLOCK_RULE rule_part_num 
PROPERTIES
(
"partition_num" = "30",
"global" = "true",
"enable" = "true"
);

Если при сканировании одной таблицы количество партиций превышает 30, запрос отклоняется.

Сценарий 3: ограничение количества сканируемых tablet​

Проблема: сканирование слишком большого количества tablet также значительно увеличивает потребление ресурсов CPU на BE.

Решение: задайте максимальное количество tablet, которое может сканировать один запрос.

CREATE SQL_BLOCK_RULE rule_tablet_num 
PROPERTIES
(
"tablet_num" = "200",
"global" = "true",
"enable" = "true"
);

Если при сканировании одной таблицы количество tablet превышает 200, запрос отклоняется.

Сценарий 4: блокировка определённых шаблонов SQL​

Проблема: некоторые шаблоны запросов, например вызовы определённых функций или выполнение опасных операций, могут приводить к чрезмерной вычислительной сложности или длительному планированию.

Решение: блокируйте такие запросы с помощью сопоставления с регулярными выражениями.

Пример 1: блокировка использования определённой функции

Следующее правило блокирует все запросы, содержащие функцию abs:

CREATE SQL_BLOCK_RULE rule_abs
PROPERTIES(
"sql"="(?i)abs\\s*\\(.+\\)",
"global"="true",
"enable"="true"
);

Разбор регулярного выражения:

  • (?i): сопоставление без учёта регистра
  • abs: имя целевой функции
  • \\s*: допускает любые пробельные символы между именем функции и открывающей скобкой
  • \\(.+\\): соответствует аргументам функции

Пример 2: блокировка опасных операций

Аналогичным образом можно использовать регулярные выражения для блокировки set global (чтобы предотвратить непреднамеренное изменение переменных) или truncate table (чтобы предотвратить непреднамеренное удаление данных).

Регулярные выражения используют синтаксис Java. Подробности см. в документации Pattern.

Сценарий 5: настройка правил для определённых пользователей​

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

Решение: создайте неглобальное правило и привяжите его к нужному пользователю.

  1. При создании правила задайте для global значение "false":

    CREATE SQL_BLOCK_RULE rule_001
    PROPERTIES (
    "sql"="select \\* from t",
    "global" = "false",
    "enable" = "true"
    );
  2. Привяжите правило к нужному пользователю:

    SET PROPERTY FOR 'root' 'SQL_block_rules' = 'rule_001';
  3. Убедитесь, что правило действует:

    MySQL root@127.0.0.1:test> select * from t;
    (1105, 'errCode = 2, detailMessage = errCode = 2, detailMessage = SQL match regex SQL block rule: rule_001')

Управление несколькими правилами:

  • Чтобы привязать к пользователю несколько правил, разделите их имена в списке запятыми, например 'rule_001,rule_002'.
  • Чтобы удалить все привязки правил к пользователю, задайте пустую строку в качестве списка правил, например SET PROPERTY FOR 'root' 'SQL_block_rules' = '';.

Примечания​

  • Метод оценки: количество сканируемых строк, партиций и tablet оценивается на этапе планирования для наихудшего случая. Учитывается только отсечение партиций и tablet, остальные условия фильтрации не учитываются. Поэтому могут блокироваться и запросы, фактический объём сканирования которых меньше заданного значения.
  • Влияние на производительность: сопоставление с регулярными выражениями требует значительных вычислительных ресурсов. Слишком большое количество правил с регулярными выражениями или их чрезмерная сложность создают значительную нагрузку на CPU FE, поэтому добавляйте их осмотрительно.
  • Временное отключение правила: измените значение свойства "enable" на "false", чтобы временно отключить правило, не удаляя его.

Workload Policy​

Workload Policy отслеживает метрики в реальном времени во время выполнения запросов и применяет к запросам, превышающим ожидаемые показатели, такие действия, как прерывание или изменение переменных. В отличие от статической оценки SQL Block Rule на этапе планирования, Workload Policy принимает решения на основе фактических данных выполнения и обеспечивает более высокую точность.

Workload Policy поддерживается начиная с Doris 2.1. Поддержка для каждого типа рабочей нагрузки указана ниже:

Тип рабочей нагрузкиПоддержка
selectДа
insert into selectДа
insert into valuesНет
stream loadДа
routine loadДа
backupНет
compactionНет

Создание и настройка​

Для создания политики используйте команду CREATE WORKLOAD POLICY. Требуется привилегия admin_priv.

Базовый синтаксис:

CREATE WORKLOAD POLICY <policy_name>
CONDITIONS(<condition_expr>)
ACTIONS(<action_expr>)
PROPERTIES('<key>'='<value>');

В следующем примере создаётся политика, которая отменяет запросы, выполняющиеся дольше 1000 мс:

CREATE WORKLOAD POLICY test_cancel_policy
CONDITIONS(query_time > 1000)
ACTIONS(cancel_query)
PROPERTIES('enabled'='true');

Условия срабатывания​

Условия определяют, когда срабатывает политика. Несколько условий разделяются запятыми (,), что соответствует логическому AND.

УсловиеОписание
usernameИмя пользователя, передаваемое с запросом. Начиная с Doris 4.1.3, его можно сочетать с метриками времени выполнения на BE, такими как query_time, be_scan_rows, be_scan_bytes и query_be_memory_bytes, для срабатывания cancel_query. Это условие поддерживает только оператор равенства (=), а имя пользователя не может быть пустым
be_scan_rowsКоличество строк, сканируемых запросом SQL в пределах одного процесса BE. При параллельном выполнении значения суммируются
be_scan_bytesКоличество байтов, сканируемых запросом SQL в пределах одного процесса BE. При параллельном выполнении значения суммируются (единица измерения: байты)
query_timeВремя выполнения запроса SQL в одном процессе BE (единица измерения: миллисекунды)
query_be_memory_bytesОбъём памяти, используемой запросом SQL в пределах одного процесса BE. При параллельном выполнении значения суммируются (единица измерения: байты)

Действия​

Действия определяют, что следует делать при выполнении условий. В настоящее время в политике можно задать только одно действие.

ДействиеОписание
cancel_queryОтменить запрос

Свойства политики​

СвойствоОписаниеЗначение по умолчанию
enabledВключена ли политика. Значение: true или falsetrue
priorityПриоритет в диапазоне от 0 до 100. Чем больше значение, тем выше приоритет. Если подходят несколько политик, применяется только политика с наивысшим приоритетом0
workload_groupИмя привязанной Workload Group. Если оно указано, политика применяется только к запросам в этой Workload Group. При пустом значении политика применяется ко всем запросамПустое значение (глобальная область действия)

Привязка к Workload Group​

Чтобы ограничить действие политики определённой Workload Group, привяжите её с помощью свойства workload_group:

CREATE WORKLOAD POLICY test_cancel_big_query
CONDITIONS(query_time > 1000)
ACTIONS(cancel_query)
PROPERTIES('workload_group'='normal');
В облачном режиме требуется полное имя

Приведённая выше форма 'workload_group'='normal' допустима только в необлачном режиме (с совмещёнными хранением и вычислениями). В облачном режиме (с разделёнными хранением и вычислениями) требуется полная форма <compute_group>.<workload_group>, например 'workload_group'='compute_group_a.normal'; иначе оператор завершится с ошибкой: workload_group must be '<compute_group>.<workload_group>' in cloud mode. Подробности см. в разделе CREATE WORKLOAD POLICY.

Примеры​

Пример 1: прерывание длительных запросов​

Следующий журнал аудита показывает, что выполнение запроса SQL обычно занимает 4.5 секунды:

MySQL [hits]> SELECT REGEXP_REPLACE(Referer, '^https?://(?:www\\.)?([^/]+)/.*$', '\\1') AS k, AVG(length(Referer)) AS l, COUNT(*) AS c, MIN(Referer) FROM hits WHERE Referer <> '' GROUP BY k HAVING COUNT(*) > 100000 ORDER BY l DESC LIMIT 25;
+-----------------------------------------------------------------------+------------------+----------+---------------------------------------------------------------------------------------------------------------------+
| k | l | c | min(Referer) |
+-----------------------------------------------------------------------+------------------+----------+---------------------------------------------------------------------------------------------------------------------+
| 1 | 85.4611926713085 | 67259319 | http://%26ad%3D1%25EA%25D0%26utm_source=web&cd=19590&input_onlist/би-2 место будущей кондицин |
| http:%2F%2Fwwww.regnancies/search&evL8gE&where=all&filmId=bEmYZc_WTDE | 69 | 207347 | http:%2F%2Fwwww.regnancies/search&evL8gE&where=all&filmId=bEmYZc_WTDE |
| http://новострашная | 31 | 740277 | http://новострашная |
| http://loveche.html?ctid | 24 | 144901 | http://loveche.html?ctid |
| http://rukodeliveresult | 23 | 226135 | http://rukodeliveresult |
| http://holodilnik.ru | 20 | 133893 | http://holodilnik.ru |
| http://smeshariki.ru | 20 | 210736 | http://smeshariki.ru |
| http:%2F%2Fviewtopic | 20 | 391115 | http:%2F%2Fviewtopic |
| http:%2F%2Fwwww.ukr | 19 | 655178 | http:%2F%2Fwwww.ukr |
| http:%2F%2FviewType | 19 | 148907 | http:%2F%2FviewType |
| http://state=2008 | 17 | 139630 | http://state=2008 |
+-----------------------------------------------------------------------+------------------+----------+---------------------------------------------------------------------------------------------------------------------+
11 rows in set (4.50 sec)

Создайте политику, которая отменяет любой запрос, выполняющийся дольше 3 секунд:

CREATE WORKLOAD POLICY test_cancel_3s_query
CONDITIONS(query_time > 3000)
ACTIONS(cancel_query);

Выполните тот же запрос SQL ещё раз: он будет прерван.

MySQL [hits]> SELECT REGEXP_REPLACE(Referer, '^https?://(?:www\\.)?([^/]+)/.*$', '\\1') AS k, AVG(length(Referer)) AS l, COUNT(*) AS c, MIN(Referer) FROM hits WHERE Referer <> '' GROUP BY k HAVING COUNT(*) > 100000 ORDER BY l DESC LIMIT 25;
ERROR 1105 (HY000): errCode = 2, detailMessage = (127.0.0.1)[CANCELLED]query cancelled by workload policy,id:12345

Пример 2: прерывание тяжёлых запросов определённого пользователя во время выполнения​

Начиная с Doris 4.1.3, можно сочетать username с метриками времени выполнения на BE, чтобы отменять только запросы определённого пользователя. Следующая политика отменяет запросы пользователя test_user, если время их выполнения на одном BE превышает 3000 мс:

CREATE WORKLOAD POLICY cancel_user_long_query
CONDITIONS(username='test_user', query_time > 3000)
ACTIONS(cancel_query);

Аналогичным образом username можно сочетать с be_scan_rows, be_scan_bytes или query_be_memory_bytes, чтобы ограничить объём сканирования или использование памяти BE для определённого пользователя.

Примечания​

  • Задержка из-за асинхронного выполнения: политики проверяются асинхронным потоком каждые 500 мс, поэтому они применяются с некоторой задержкой. Очень короткие запросы могут завершиться до проверки и избежать применения политики.
  • Механизм приоритетов: запрос может соответствовать нескольким политикам, но применяется только политика с наивысшим приоритетом (наибольшим значением priority).
  • Ограничение на изменение: в настоящее время нельзя напрямую изменить действие и условие существующей политики. Удалите политику и создайте её заново.