ClickHouse 23.9 LTS: обновляем кластер и тестируем Parallel Replicas на длинных временных диапазонах
ClickHouse 23.9 получил статус LTS. Обновляем аналитический кластер и тестируем Parallel Replicas на агрегациях по большим диапазонам дат - прирост около 40%.
ClickHouse 23.9 LTS выпущен - улучшенный Parallel Replicas, SharedMergeTree для cloud-native деплоя, октябрь 2023
ClickHouse 23.9 стал очередной LTS-веткой. Мы с нетерпением ждали именно этого: с апрельского апгрейда на 23.3 у нас висел открытый вопрос по Parallel Replicas - функция тогда ещё была в достаточно сыром состоянии на нагрузке с большими временными диапазонами. В 23.9 команда ClickHouse говорит об улучшенном алгоритме распределения гранул между репликами. Самое время проверить на managed-сопровождении.
Что изменилось в Parallel Replicas
Исторически у нас с этой функцией отношения неоднозначные. В декабре 2022 мы первый раз тестировали её на 22.12 и получили хорошие результаты на «горячих» запросах по последним неделям данных. Но на запросах с диапазоном в несколько месяцев или год картина была хуже: координатор неравномерно делил гранулы между узлами, одна реплика заканчивала быстро и простаивала, пока другая дожёвывала хвост. Прирост был, но нестабильный.
В 23.9 переработан алгоритм динамического распределения гранул - координатор теперь выдаёт гранулы пачками и корректирует распределение по мере выполнения, а не делит пул статически в начале запроса. Плюс улучшена обработка марков (mark files) при неравномерных партах - это как раз то, что проявлялось на длинных временных диапазонах, где партов много и они разного размера.
Ещё в релизе - SharedMergeTree как движок для cloud-native деплоев, где несколько узлов работают с общим объектным хранилищем. Нас это сейчас меньше касается: кластер клиента живёт на железе, не в облаке, и ReplicatedMergeTree нас устраивает. Но факт интересный - видно, что команда двигается в сторону разделения вычислений и хранения.
Кластер и стенд
Кластер трёхнодовый ReplicatedMergeTree, ClickHouse 23.3.x. Основная таблица событий - несколько сотен гигабайт горячих данных, партиционирование по месяцам. Нагрузка смешанная: короткие OLTP-образные запросы за последние дни и тяжёлые аналитические агрегации за квартал или год.
Апгрейд с 23.3 на 23.9 через пакетный менеджер: по одному узлу, с проверкой кластерного здоровья между перезапусками. Прошло без сюрпризов - всё-таки обе версии LTS, и схема таблиц не менялась.
# Обновление по одному узлу
apt-get install -y clickhouse-server=23.9.4.11 clickhouse-client=23.9.4.11
systemctl restart clickhouse-server
# Проверка кластера после перезапуска
SELECT host_name, version(), uptime()
FROM clusterAllReplicas('default_cluster', system.one)
Что меряли
Три класса запросов по временному диапазону:
- Короткий диапазон - последние 7 дней. Данных немного, партов мало.
- Средний диапазон - последние 3 месяца. Типичный аналитический отчёт.
- Длинный диапазон - год и более. Самые тяжёлые запросы, за которые ранее жаловались.
Сравниваем 23.3 и 23.9 с включёнными Parallel Replicas:
SET allow_experimental_parallel_reading_from_replicas = 1;
SET max_parallel_replicas = 3;
SET parallel_replicas_for_non_replicated_merge_tree = 0;
На 23.3 мы использовали parallel_replicas_custom_key с ручным партиционированием по полю - это был костыль для более равномерного распределения. В 23.9 попробовали без него.
Результаты
На коротком диапазоне разница в пределах погрешности - что 23.3, что 23.9. Данных мало, накладные расходы на координацию съедают прирост. Здесь Parallel Replicas скорее вредят, чем помогают, это было известно ещё с прошлого года.
На среднем диапазоне 23.9 без ручного custom_key показал примерно то же, что 23.3 с кастомным ключом. То есть алгоритм из коробки дотянулся до уровня, который раньше требовал ручной настройки. Приятно.
На длинном диапазоне - вот тут интересно. 23.3 с кастомным ключом давал нестабильный прирост: в зависимости от запроса от 15% до 35%, с выбросами в обе стороны. В 23.9 без кастомного ключа прирост на год данных стабильно вышел в район 40% на агрегациях с GROUP BY по нескольким измерениям. Дисперсия заметно меньше - координатор явно лучше балансирует нагрузку между репликами в динамике.
Одна ремарка: 40% - это на нашем конкретном железе и нашем конкретном профиле данных. Три однородных узла, примерно равный объём партов на каждом. На кластерах с асимметричными нодами результат будет другим.
Что убрали и что добавили в конфиг
Старый костыль с parallel_replicas_custom_key убрали - он больше не нужен, и на 23.9 его присутствие, судя по всему, мешает новому алгоритму работать правильно: координатор пытается совместить статическое разбиение по кастомному ключу с динамическим алгоритмом, и получается хуже, чем без него.
Добавили мониторинг на уровне запроса через system.query_log - смотрим на read_rows, read_bytes в разбивке по репликам. В 23.9 появилось чуть больше деталей в трейсах параллельного чтения, что упрощает диагностику перекосов.
Промежуточный итог
Апгрейд оправдался, хотя и без фейерверка. Параллельные реплики на длинных диапазонах стали работать предсказуемо - это важнее, чем просто «стало быстрее», потому что непредсказуемый прирост хуже предсказуемого умеренного. Клиент уже перестал получать жалобы на годовые отчёты, которые раньше иногда таймаутились.
SharedMergeTree в наш план не входит - не наш сценарий. Но если кто-то строит новый кластер с прицелом на S3 как основное хранилище, стоит смотреть именно в эту сторону.
Что осталось открытым: query optimizer из 23.3 по-прежнему включён, и мы не до конца понимаем взаимодействие между его трансформациями и параллельным чтением с реплик. На некоторых запросах видим чуть неожиданные планы. Нужно разобраться, прежде чем делать выводы.