Параллельные реплики
Параллельные реплики — это механизм горизонтального масштабирования чтения в ClickHouse. Вместо того чтобы один узел читал всю таблицу, запрос динамически распределяет гранулы между несколькими репликами шарда. Каждая реплика читает свою часть данных параллельно, coordinator объединяет результаты.
Это даёт линейное ускорение чтения при добавлении реплик в шард — без дополнительного шардирования данных.
Настройка
-- Включить параллельные реплики для конкретного запроса
SELECT
toStartOfHour(event_time) AS hour,
count() AS events,
sum(amount) AS revenue
FROM events_local
WHERE event_date >= today() - 30
GROUP BY hour
ORDER BY hour
SETTINGS
enable_parallel_replicas = 1,
max_parallel_replicas = 3,
cluster_for_parallel_replicas = 'mycluster',
parallel_replicas_min_number_of_rows_per_replica = 500000;
| Параметр | Значение | Описание |
|---|---|---|
enable_parallel_replicas | 1 | Включить параллельное чтение с реплик |
max_parallel_replicas | 2-4 | Максимум реплик для участия в запросе |
cluster_for_parallel_replicas | ’mycluster’ | Кластер из remote_servers конфига |
parallel_replicas_min_number_of_rows_per_replica | 500000 | Минимум строк на реплику (иначе нет смысла) |
Переименование setting в ClickHouse 24.x+
В ClickHouse 23.x/24.x параметр назывался allow_experimental_parallel_reading_from_replicas. Начиная с версии 24.x (PR #63151), он переименован в enable_parallel_replicas. В ClickHouse 26.3 LTS используйте enable_parallel_replicas.
Старое название allow_experimental_parallel_reading_from_replicas сохраняется как alias для обратной совместимости, но является устаревшим (deprecated). Если вы видите это название в старых конфигурациях или статьях — замените на enable_parallel_replicas.
Как это работает: гранулярное распределение
Параллельные реплики работают на уровне гранул (granule) — минимальных единиц чтения в ClickHouse (по умолчанию 8192 строк). Coordinator динамически распределяет гранулы между репликами по принципу task stealing:
Coordinator (планировщик гранул)
Coordinator: получает запрос SELECT, определяет список гранул в таблице через sparse index. Делит диапазон гранул динамически между репликами. Task stealing: если реплика закончила свою часть раньше, она запрашивает следующие гранулы у coordinator.Replica 1
Replica 1: получает от coordinator диапазон гранул 1-100 (примерно 800K строк при index_granularity=8192). Читает локально из своих part-файлов, применяет WHERE, делает локальную агрегацию GROUP BY. Отправляет mergeable state coordinator-у.Replica 2
Replica 2: обрабатывает свою порцию гранул параллельно с Replica 1. Каждая реплика работает независимо, без блокировок между собой. Линейное ускорение при одинаковой производительности реплик.Replica 3
Replica 3: если max_parallel_replicas=3. Task stealing: если Replica 2 закончила быстро, coordinator может передать ей дополнительные гранулы от Replica 3's range. Динамическое балансирование без статического разбиения.Coordinator: финальный merge результатов
Coordinator объединяет частичные результаты от всех реплик: MergingAggregated для GROUP BY, финальный ORDER BY, LIMIT. Идентично финальному merge в обычном Distributed query -- coordinator получает промежуточные агрегатные состояния (-Merge compatible) от каждой реплики.Требования
Параллельные реплики работают корректно при соблюдении условий:
1. New Analyzer (enable_analyzer=1)
-- Проверить текущее значение
SELECT value FROM system.settings WHERE name = 'enable_analyzer';
-- Включить для сессии (по умолчанию=1 в 26.3)
SET enable_analyzer = 1;
New Analyzer (Query Analysis framework) является обязательным для параллельных реплик начиная с ClickHouse 24.x. В ClickHouse 26.3 LTS он включён по умолчанию (enable_analyzer=1).
2. Достаточный размер таблицы
Параллельные реплики эффективны только при чтении большого количества гранул:
-- Проверить количество гранул в таблице
SELECT
table,
sum(marks) AS total_granules,
sum(rows) AS total_rows
FROM system.parts
WHERE database = 'db' AND table = 'events_local' AND active
GROUP BY table;
-- Рекомендуется: > 10,000 гранул для ощутимого эффекта
При parallel_replicas_min_number_of_rows_per_replica=500000 и таблице из 100K строк: параллельные реплики автоматически откажутся от параллелизма (недостаточно строк на реплику).
3. Топология с несколькими репликами
Требуется топология типа 1S_3R (один шард, три реплики) или 2S_2R. Для кластера с 1S_1R параллельные реплики не применимы — нет второй реплики для параллельного чтения.
Ключевые выводы
- Параллельные реплики — read scale-out: одна шардированная таблица читается несколькими репликами параллельно по гранулам.
- enable_parallel_replicas — актуальное название (26.3 LTS). Устаревшее:
allow_experimental_parallel_reading_from_replicas(до 24.x). - Гранулярное распределение с task stealing: coordinator динамически балансирует нагрузку между репликами — нет статического разбиения.
- Требования: New Analyzer (default в 26.3), достаточный размер таблицы, топология с несколькими репликами.
- parallel_replicas_min_number_of_rows_per_replica: защита от накладных расходов на маленьких таблицах — параллелизм включается только при достаточном объёме данных.