Keeper убрал Java из координации ClickHouse

Keeper убрал Java из координации ClickHouse

 

ClickHouse всегда нуждался в строгой координации для репликации, распределённых DDL и назначения блоков, хотя сами данные расходятся по eventually consistent модели. ZooKeeper давал нужную семантику сессий, эфемерных узлов и последовательных znode, но требовал отдельного Java-процесса. Keeper реализовал совместимый протокол на C++ с Raft, а затем получил ClickHouse-специфичные оптимизации. В итоге инженеры получили возможность убрать JVM из стека без изменения логики репликации.

 

Почему ZooKeeper изначально подошёл

Репликация в ClickHouse строится вокруг ReplicatedMergeTree. Таблицы могут расходиться по частям, слияниям и фоновым задачам, но номера блоков, очереди репликации и порядок DDL должны назначаться однозначно. ZooKeeper предоставлял иерархическое хранилище с watches и multi-операциями, где чтения выполнялись локально на подключённом узле, а запись проходила через кворум. Это позволяло хранить небольшие метаданные с высокой надёжностью, не мешая основному потоку данных.

Инженеры добавили поддержку ZooKeeper ещё в 2014 году, и с тех пор поведение репликации жёстко завязано на его модель. Эфемерные узлы отслеживают активные реплики, последовательные узлы гарантируют уникальность номеров блоков. Любая замена должна воспроизводить эти свойства точно, иначе существующие кластеры рискуют получить расхождения или зависания. Для команд, решающих вопрос о переходе, важно понимать, что ZooKeeper здесь выступает не просто хранилищем, а источником сильной согласованности для критически важных метаданных. Без точного воспроизведения сессий и эфемерных узлов система теряет способность быстро обнаруживать отказы реплик и предотвращать дублирование данных.

 

Почему простая замена не сработала

etcd и Consul используют другие примитивы — они не дают последовательных узлов и эфемерных сессий в том же виде. Переписывание логики репликации под них потребовало бы серьёзных изменений в StorageReplicatedMergeTree и Distributed DDL. Keeper пошёл другим путём — полностью повторил ZooKeeper API поверх Raft, сохранив формат znodes и поведение watches. Это позволило мигрировать без переписывания кода ClickHouse.

Однако совместимость по протоколу не означала одинаковую производительность. Первые версии Keeper показывали заметно больше задержек на запись и хуже справлялись с большим числом клиентов. Для кластеров с десятками реплик и частыми DDL такие задержки становились заметны. Инженеры получали корректную, но не всегда достаточно быструю замену. При оценке Keeper важно учитывать, что Raft обеспечивает отказоустойчивость через кворум, но начальная реализация несла overhead на сериализацию и обработку запросов. Для решения о внедрении это означает необходимость сравнивать не только функциональность, но и реальную задержку на типичных операциях записи метаданных.

 

Как развивалась производительность

Последующие релизы добавили batched apply, улучшенный snapshot и более эффективную работу с диском. Убрали лишние аллокации, оптимизировали обработку сессий и watches. В результате Keeper приблизился к ZooKeeper по latency на типичных workload ClickHouse. При этом он остался однопроцессным C++-приложением без сборки мусора и с предсказуемым потреблением памяти.

Важно, что Keeper теперь не просто «ZooKeeper на другом языке». В нём появились ClickHouse-специфичные улучшения: tighter интеграция с метриками сервера, упрощённая настройка под один и тот же порт, меньшее число параметров. Для команд это снижает поверхность ошибок при обновлениях и упрощает мониторинг. С точки зрения принятия решения такие оптимизации снижают риски, связанные с управлением памятью и непредсказуемыми паузами, которые характерны для JVM. Однопроцессная модель упрощает бэкапы и диагностику, что особенно ценно в средах без managed-сервисов.

 

Что учитывать при внедрении в РФ

В российских компаниях ClickHouse часто стоит на собственных мощностях без доступа к managed-сервисам. Keeper упрощает эксплуатацию: один бинарник вместо JVM, меньше настроек кучи и сборщика мусора, проще бэкапы. При этом нужно проверить совместимость версии Keeper с уже используемым ClickHouse — особенно если кластер обновлялся поэтапно. Для нагруженных систем стоит провести нагрузочное тестирование именно на своих сценариях DDL и частоте создания частей, потому что поведение при пиковых нагрузках отличается от ZooKeeper.

Миграция выполняется через постепенное переключение реплик на Keeper-кластер, при этом старый ZooKeeper можно оставить на время отката. Главный риск — не в протоколе, а в недооценке объёма метаданных и количества watches при большом числе таблиц. При правильной оценке Keeper даёт устойчивую работу без Java-зависимостей и с меньшими операционными издержками. Для решения о переходе ключевыми факторами становятся снижение операционной нагрузки и предсказуемость потребления ресурсов, однако требуется тщательная проверка совместимости и проведение тестов на реальных нагрузках, чтобы избежать скрытых проблем с производительностью или отказоустойчивостью.

 

Источник

Это краткий разбор материала Altinity. Полная версия с примерами кода, схемами и деталями реализации — в оригинале: Keeper убрал Java из координации ClickHouse.

Курс по теме — Построение DWH на ClickHouse

 

Построение DWH на ClickHouse

Код курса
CLICH
Ближайшая дата курса
12 октября, 2026
Продолжительность
24 ак.часов
Стоимость обучения
76 800