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

Настройка параллелизма

Параллелизм (parallel_pipeline_task_num) определяет количество рабочих задач, которые один Fragment использует при выполнении на BE. Это ключевой параметр для эффективного использования многоядерных CPU и сокращения времени выполнения запросов.

Что проверить перед настройкой​

  • Вы проверили количество ядер CPU на BE: оно определяет верхнюю границу параллелизма.
  • Вы определили узкое место с помощью Profile или метрик мониторинга: вычисления, сканирование или накладные расходы на планирование задач.
  • Вы понимаете характер текущей нагрузки: точечный запрос, JOIN/агрегация, нагрузочное тестирование или сложный запрос.
  • При значении по умолчанию (0, что означает половину количества ядер CPU) производительность действительно ниже ожидаемой.

Основные понятия​

  • Параллелизм MPP: каждый запрос выполняется параллельно на нескольких BE.
  • Параллелизм внутри BE: многопоточное выполнение ускоряет обработку Fragment на одном BE.
  • parallel_pipeline_task_num: количество рабочих задач, которые один Fragment использует при выполнении. Значение по умолчанию 0 означает половину количества ядер CPU на BE.
  • Поддерживаемые операторы: все операторы Query, DML и DDL поддерживают параллельное выполнение.

Принципы настройки​

Увеличение параллелизма не всегда улучшает производительность:

  1. Повышение параллелизма позволяет полностью использовать ресурсы многоядерных CPU и сократить время выполнения отдельного запроса.
  2. Однако оно добавляет операторы Shuffle для перераспределения данных и логику синхронизации потоков, что приводит к лишним затратам ресурсов.
  3. Значение по умолчанию уже обеспечивает баланс между выполнением отдельных запросов и конкурентной нагрузкой, поэтому ручная настройка обычно не требуется.
  4. Адаптивные стратегии Doris продолжают совершенствоваться. Предпочитайте настройку на уровне SQL или конкретного сценария, а не на глобальном уровне.

Рекомендации по настройке для разных сценариев​

В следующих примерах предполагается, что BE располагает 16 ядрами CPU.

Сводная таблица сценариев​

Сценарий запросаРекомендуемый параллелизмОбоснование
Точечный запрос к одной таблице / WHERE для небольшого объёма данных / LIMIT / использование материализованного представления1В запросе есть только один Fragment. Узкое место — поток сканирования: он независим от потока выполнения запроса, а параллелизм сканирования регулируется адаптивно. Поэтому дополнительные параллельные потоки выполнения запроса не нужны.
JOIN двух таблиц на большом наборе данных / запрос с агрегацией (интенсивные вычисления)16Нагрузка связана с вычислениями. Если CPU загружен не полностью, повышение параллелизма позволяет задействовать все ядра. Однако увеличивать его без ограничений не следует: например, значение 48 лишь добавляет накладные расходы на планирование задач.
Нагрузочное тестирование1Параллельно выполняющиеся запросы уже полностью загружают CPU, а избыточный параллелизм лишь добавляет накладные расходы на планирование потоков и работу механизма планирования.
Сложный запросЗначение по умолчаниюПодбирайте значение с учётом Profile и нагрузки на сервер. Попробуйте поэтапно уменьшать его: 4 -> 2 -> 1, наблюдая за результатом.

Сценарий 1: простые операции с одной таблицей​

  • Характеристики: один Fragment; узкое место — поток сканирования, параллелизм которого уже регулируется адаптивно.
  • Рекомендация: parallel_pipeline_task_num = 1.
  • Обоснование: поток сканирования и поток выполнения запроса независимы. Увеличение количества параллельных потоков выполнения запроса не ускоряет обработку, если узкое место — сканирование.

Сценарий 2: JOIN/агрегация на больших наборах данных​

  • Характеристики: вычислительно интенсивная нагрузка, при которой CPU загружен не полностью.
  • Рекомендация: увеличьте параллелизм относительно значения по умолчанию, например задайте parallel_pipeline_task_num = 16.
  • Обоснование: это позволяет использовать возможности параллельного выполнения движка Pipeline и полностью загрузить CPU. Однако увеличивать параллелизм без ограничений не следует: накладные расходы на планирование потоков и работу механизма планирования могут перевесить выигрыш.

Сценарий 3: нагрузочное тестирование​

  • Характеристики: одновременно выполняется достаточно запросов, чтобы они уже полностью загружали CPU.
  • Рекомендация: parallel_pipeline_task_num = 1.
  • Обоснование: это позволяет избежать накладных расходов на планирование, возникающих при повышении параллелизма отдельного запроса в условиях высокой конкурентной нагрузки.

Сценарий 4: сложные запросы​

  • Характеристики: сложный план выполнения, в котором трудно сразу определить узкое место.
  • Рекомендация: начните со значения по умолчанию, затем с учётом Profile и нагрузки на сервер поэтапно изменяйте его: 4 -> 2 -> 1, наблюдая за результатом.

Способы настройки​

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

Сравнение способов​

СпособОбласть действияКогда применятьРиск
SQL HINTОдин оператор SQLНастройка конкретного медленного SQL-запросаБез побочных эффектов; предпочтительный способ
Переменная сессииТекущая сессияГруппа запросов в одной сессииЗапросы к одной строке также используют эту настройку, что может снизить производительность
Глобальная переменнаяВсе новые подключения в кластереНастройка загрузки CPU во всём кластереСамая широкая область воздействия; применяйте с осторожностью

Настройка на уровне SQL​

  • Назначение: с помощью HINT точно задать параллелизм отдельного оператора SQL. Этот способ обеспечивает наибольшую гибкость.

  • Команда:

    SELECT /*+SET_VAR(parallel_pipeline_task_num=8)*/ *
    FROM nation, lineitem
    WHERE lineitem.l_suppkey = nation.n_nationkey;

    SELECT /*+SET_VAR(parallel_pipeline_task_num=8,runtime_filter_mode=global)*/ *
    FROM nation, lineitem
    WHERE lineitem.l_suppkey = nation.n_nationkey;
  • Примечания: в том же HINT можно задать и другие переменные сессии, например runtime_filter_mode.

Настройка на уровне сессии​

  • Назначение: применить одинаковую настройку параллелизма ко всем операторам SQL в текущей сессии.

  • Команда:

    SET parallel_pipeline_task_num = 8;
  • Примечания: в пределах сессии даже точечные запросы к одной строке выполняются с этим параллелизмом, что может замедлить простые запросы.

Глобальная настройка​

  • Назначение: применить настройку ко всем новым подключениям, изменив поведение по умолчанию во всём кластере.

  • Команда:

    SET GLOBAL parallel_pipeline_task_num = 8;
  • Примечания: используйте этот способ только тогда, когда действительно требуется изменить загрузку CPU во всём кластере. В остальных случаях сохраняйте значение по умолчанию.

Частые вопросы и устранение проблем​

Вопрос 1: почему запрос стал медленнее после увеличения параллелизма?​

Слишком высокий параллелизм увеличивает накладные расходы на Shuffle и синхронизацию потоков. Сам механизм планирования также требует ресурсов. Например, значение 48 на сервере с 16 ядрами практически не даёт выигрыша и лишь увеличивает затраты на планирование. Начните со значения по умолчанию и изменяйте его поэтапно: 4 -> 2 -> 1.

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

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

Вопрос 4: что означает значение по умолчанию 0?​

parallel_pipeline_task_num = 0 означает, что BE автоматически использует половину количества ядер CPU. Это значение обеспечивает баланс между производительностью отдельного запроса и пропускной способностью при конкурентной нагрузке. В большинстве сценариев менять его не требуется.

Вопрос 5: стоит ли задавать параллелизм глобально или использовать SQL HINT?​

Предпочитайте SQL HINT для настройки отдельных медленных SQL-запросов. Используйте SET GLOBAL только после того, как убедитесь, что загрузку CPU необходимо скорректировать во всём кластере.

ПараметрНазначениеЗначение по умолчанию
parallel_pipeline_task_numКоличество рабочих задач для одного Fragment на BE0 (количество ядер CPU на BE / 2)
runtime_filter_modeРежим работы Runtime Filter; часто настраивается вместе с параллелизмомСм. документацию по Runtime Filter
На этой странице