Архитектура сервера: thread pools, merge selector, жизненный цикл запроса
Понимание внутренней архитектуры ClickHouse — ключ к диагностике производительности. Три основных пула потоков управляют разными типами работы: фоновые периодические задачи, фоновые MergeTree-операции, и пользовательские запросы. Жизненный цикл запроса от соединения до выполнения проходит через несколько чётко разделённых фаз.
Thread Pools: три пула для разных задач
BackgroundSchedulePool
Пул для периодических задач с фиксированным расписанием. Не конкурирует с пользовательскими запросами.
-- Настройки BackgroundSchedulePool
SELECT name, value, description
FROM system.server_settings
WHERE name LIKE 'background_schedule_pool_size%';
-- Мониторинг: активные задачи в pool
SELECT metric, value
FROM system.metrics
WHERE metric LIKE 'BackgroundSchedule%';
Ключевые задачи BackgroundSchedulePool:
- TTL merges: удаление или перемещение данных по истечении TTL
- Refreshable Materialized Views: обновление MV по расписанию (
REFRESH EVERY ... HOUR) - Dictionary reloads: периодическая перезагрузка словарей при истечении
LIFETIME
MergeTreeBackgroundExecutor
Центральный пул для всех фоновых MergeTree-операций. Использует приоритизацию коротких задач: небольшие merge-задачи выполняются раньше крупных, чтобы не допустить накопления частей.
-- Ключевые настройки MergeTreeBackgroundExecutor
SELECT name, value
FROM system.merge_tree_settings
WHERE name IN (
'max_background_merges_with_ttl_allowed',
'number_of_free_entries_in_pool_to_lower_max_size_of_merge',
'max_bytes_to_merge_at_max_space_in_pool'
);
-- Мониторинг: активные merges и mutations
SELECT
database,
table,
result_part_name,
reason,
progress,
formatReadableSize(total_size_bytes_compressed) AS size
FROM system.merges
ORDER BY elapsed DESC;
-- Количество фоновых операций в очереди
SELECT metric, value
FROM system.metrics
WHERE metric IN (
'BackgroundMergesAndMutationsPoolTask',
'BackgroundFetchesPoolTask',
'BackgroundMovesPoolTask'
);
Настройки размера пула (в config.xml или пользовательских профилях):
<!-- /etc/clickhouse-server/config.d/background_pool.xml -->
<clickhouse>
<background_pool_size>32</background_pool_size>
<background_move_pool_size>8</background_move_pool_size>
<background_fetches_pool_size>16</background_fetches_pool_size>
<background_schedule_pool_size>128</background_schedule_pool_size>
</clickhouse>
Global Thread Pool
Обрабатывает пользовательские запросы, соединения и I/O. Количество потоков на запрос управляется через max_threads.
-- Текущее использование Global Thread Pool
SELECT metric, value
FROM system.metrics
WHERE metric IN ('GlobalThread', 'GlobalThreadActive', 'HTTPConnection', 'TCPConnection');
-- Ключевые настройки для запросов
SELECT name, value
FROM system.settings
WHERE name IN ('max_threads', 'max_insert_threads', 'max_distributed_connections');
Merge Selector: как выбираются части для слияния
MergeTreeBackgroundExecutor использует merge selector для выбора следующего набора частей для слияния. Алгоритм балансирует между:
- Количеством частей (чем больше частей, тем медленнее SELECT)
- Размером частей (большие части дороже мержить, но дают лучшее сжатие)
- Временем ожидания (части не должны накапливаться)
-- Мониторинг: количество частей по таблицам (>300 частей -- сигнал проблемы)
SELECT
database,
table,
count() AS parts_count,
sum(rows) AS total_rows,
formatReadableSize(sum(bytes_on_disk)) AS total_size
FROM system.parts
WHERE active = 1
GROUP BY database, table
ORDER BY parts_count DESC
LIMIT 10;
-- Настройки merge selector
SELECT name, value, description
FROM system.merge_tree_settings
WHERE name LIKE '%merge%'
ORDER BY name;
Жизненный цикл запроса
New Analyzer (ClickHouse 24.3+)
New Analyzer является default с ClickHouse 24.3. Улучшенная обработка сложных запросов:
-- Проверить, что New Analyzer активен (default true в 24.3+)
SELECT value FROM system.settings WHERE name = 'allow_experimental_analyzer';
-- Если нужно отключить для конкретного запроса (для отладки)
SET allow_experimental_analyzer = 0;
SELECT count() FROM events WHERE user_id > 1000;
-- Explain: увидеть, как Analyzer разбирает запрос
EXPLAIN AST SELECT user_id, count() FROM events GROUP BY user_id;
Pipeline execution
-- Увидеть execution pipeline для запроса
EXPLAIN PIPELINE
SELECT user_id, count()
FROM events
WHERE event_time >= today() - 7
GROUP BY user_id
ORDER BY count() DESC
LIMIT 10;
-- Мониторинг активных запросов во время выполнения
SELECT
query_id,
user,
elapsed,
read_rows,
read_bytes,
memory_usage,
query
FROM system.processes
ORDER BY elapsed DESC;
Ключевые настройки
-- Настройки thread pools (для диагностики)
SELECT name, value
FROM system.server_settings
WHERE name IN (
'background_pool_size',
'background_move_pool_size',
'background_fetches_pool_size',
'background_schedule_pool_size',
'max_thread_pool_size'
);
-- Настройки max_threads на запрос
SELECT name, value
FROM system.settings
WHERE name IN ('max_threads', 'max_insert_threads');
Ключевые выводы
BackgroundSchedulePoolобрабатывает периодические задачи (TTL merges, refreshable MV, dictionary reloads) по расписанию. Не конкурирует с запросами пользователей за потоки.MergeTreeBackgroundExecutorобъединяет все фоновые MergeTree-операции: merges, mutations, fetches, moves. Использует short-task prioritization: небольшие merge-задачи выполняются раньше крупных.- Global Thread Pool обрабатывает пользовательские запросы и I/O.
max_threadsограничивает параллелизм на уровне одного запроса,background_pool_size— фоновые операции. - Жизненный цикл запроса: connection -> parsing -> analysis (New Analyzer 24.3+) -> optimization -> pipeline build -> execution. New Analyzer улучшает обработку сложных подзапросов и CTE.
- Merge selector балансирует между количеством частей (>300 частей на таблицу — сигнал проблемы) и стоимостью слияния.
system.mergesпоказывает активные операции,system.metrics— загрузку пулов.