ReplicatedMergeTree и ClickHouse Keeper
ReplicatedMergeTree — движок, который превращает обычную MergeTree-таблицу в реплицируемую. Он не работает сам по себе: для координации всех реплик требуется внешний сервис — ClickHouse Keeper. Keeper хранит метаданные репликации, координирует DDL-операции и отслеживает состояние каждой реплики. Без Keeper ReplicatedMergeTree не может принять ни одну запись.
Что хранит Keeper
Keeper организует данные в иерархию znodes — аналог ZooKeeper-узлов. Каждая реплицируемая таблица получает собственное поддерево в Keeper.
Конфигурация ReplicatedMergeTree
ReplicatedMergeTree принимает два параметра: путь в Keeper и имя реплики. В production оба параметра задаются через макросы сервера, а не жёстко прописываются.
-- Создание ReplicatedMergeTree с макросами (production-паттерн)
CREATE TABLE events_local
(
event_time DateTime,
user_id UInt64,
event_type LowCardinality(String),
properties String
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/db/events_local', '{replica}')
PARTITION BY toYYYYMM(event_time)
ORDER BY (event_type, user_id, event_time);
Макросы {'{shard}'} и {'{replica}'} подставляются из секции <macros> конфига сервера. Первый параметр — путь в Keeper (одинаковый для всех реплик одного шарда), второй — уникальное имя реплики на каждом узле.
Если два шарда имеют одинаковый путь в Keeper (например, оба используют жёстко прописанный /clickhouse/tables/01/db/events), они начнут реплицировать данные друг другу как одна таблица. Это катастрофическая ошибка конфигурации. Всегда используйте макрос {'{shard}'} в пути.
Конфигурация Keeper на сервере ClickHouse
Каждый ClickHouse-сервер подключается к Keeper через секцию <zookeeper> в конфиге. Порт 9181 — клиентское соединение (не путать с 9234 — Raft-протокол между узлами Keeper).
<!-- /etc/clickhouse-server/config.d/keeper.xml -->
<clickhouse>
<!-- Keeper client: порт 9181 -->
<zookeeper>
<node>
<host>keeper-01</host>
<port>9181</port>
</node>
<node>
<host>keeper-02</host>
<port>9181</port>
</node>
<node>
<host>keeper-03</host>
<port>9181</port>
</node>
</zookeeper>
<!-- Макросы: подставляются в путь Keeper и имя реплики -->
<macros>
<shard>01</shard>
<replica>clickhouse-01</replica>
</macros>
</clickhouse>
Порт 9181 — это клиентский порт Keeper, который используют ClickHouse-серверы. Порт 9234 — Raft-протокол, который Keeper-узлы используют для общения между собой при выборах лидера. Firewall должен открыть оба: 9181 от CH-серверов к Keeper, 9234 между Keeper-узлами.
Диаграмма состояний реплики
Ключевые выводы
- ReplicatedMergeTree требует Keeper для работы — без Keeper все вставки завершаются ошибкой сессии.
- Keeper хранит журнал репликации, состояние реплик, блоки дедупликации и метаданные мутаций в иерархии znodes.
- Путь в Keeper должен содержать макрос
{'{shard}'}для изоляции шардов — иначе разные шарды начнут реплицироваться как одна таблица. - Макросы
{'{shard}'}и{'{replica}'}подставляются из<macros>в конфиге каждого ClickHouse-сервера. - ClickHouse-серверы подключаются к Keeper по порту 9181 (клиентский), Keeper-узлы общаются между собой по 9234 (Raft).