Replicated database engine
Replicated — это движок базы данных, который автоматически транслирует все DDL-операции на все узлы кластера без явного указания ON CLUSTER. Вместо ручного управления DDL на каждом узле, все изменения схемы проходят через ClickHouse Keeper и применяются синхронно на всех репликах.
Создание Replicated базы данных
Синтаксис создания Replicated базы данных:
CREATE DATABASE mydb
ON CLUSTER mycluster
ENGINE = Replicated('/clickhouse/databases/mydb', '{shard}', '{replica}');
Параметры:
/clickhouse/databases/mydb— путь в Keeper для хранения метаданных DDL{shard}— макрос, заменяется значением из конфига (например,01,02){replica}— макрос для идентификации реплики (например,replica-1)
После создания все DDL-операции внутри mydb автоматически реплицируются. ON CLUSTER нужен только при самом создании базы данных — после этого он больше не требуется.
Параметры {shard} и {replica} — это макросы из секции <macros> конфига ClickHouse. Они должны быть настроены на каждом узле кластера. Если макросы не заданы, Keeper путь будет содержать литеральные строки {shard} и {replica}, что приведёт к конфликтам.
DDL без ON CLUSTER
После создания Replicated базы данных, все DDL внутри неё выполняются без ON CLUSTER:
-- Создать таблицу (без ON CLUSTER -- Replicated DB применит на всех узлах)
CREATE TABLE mydb.events (
event_id UInt64,
user_id UInt32,
event_type String,
event_time DateTime
) ENGINE = ReplicatedMergeTree ORDER BY event_id;
-- Добавить колонку (без ON CLUSTER)
ALTER TABLE mydb.events ADD COLUMN region String DEFAULT '';
-- Создать Materialized View (без ON CLUSTER)
CREATE MATERIALIZED VIEW mydb.events_mv
ENGINE = ReplicatedSummingMergeTree ORDER BY (user_id, event_type)
AS SELECT user_id, event_type, count() AS cnt FROM mydb.events GROUP BY user_id, event_type;
-- Удалить таблицу (без ON CLUSTER)
DROP TABLE mydb.events;
Всё это применится на каждом узле, который является частью базы данных mydb. Механизм работает через DDL-журнал в Keeper — каждый DDL-запрос записывается как entry, остальные узлы получают его через watch-механизм Keeper и исполняют.
Replicated database engine — рекомендуемый подход для новых кластеров ClickHouse. Он устраняет классический источник ошибок: DDL, применённый на одной реплике, но забытый на других. С Replicated DB вся кластерная конфигурация схемы консистентна по определению.
Auto-created cluster
При создании Replicated базы данных ClickHouse автоматически регистрирует кластер с именем, совпадающим с именем базы данных. Этот кластер виден в system.clusters:
SELECT
cluster,
shard_num,
replica_num,
host_name,
port
FROM system.clusters
WHERE cluster = 'mydb'
ORDER BY shard_num, replica_num;
Пример вывода для кластера из 2 шардов с 1 репликой:
cluster | shard_num | replica_num | host_name | port
--------|-----------|-------------|-----------------|------
mydb | 1 | 1 | clickhouse-01 | 9000
mydb | 2 | 1 | clickhouse-02 | 9000
Этот автоматически созданный кластер можно использовать в Distributed table:
-- Distributed table использует auto-created cluster 'mydb'
CREATE TABLE mydb.events_dist
ENGINE = Distributed('mydb', 'mydb', 'events', xxHash64(user_id));
ON CLUSTER vs Replicated database
Разница между подходами: ON CLUSTER — явный DDL для каждой операции, Replicated database engine — неявный для всех DDL внутри базы данных. В ON CLUSTER легко ошибиться (забыть указать, указать неверный кластер). В Replicated DB ошибка невозможна — DDL физически не может быть применён только на одном узле.
Ключевые выводы
- ENGINE = Replicated превращает базу данных в единицу репликации DDL: все CREATE/ALTER/DROP внутри неё автоматически транслируются на все узлы.
- Синтаксис:
ENGINE = Replicated('/clickhouse/databases/mydb', '{shard}', '{replica}')— путь в Keeper + два макроса. - ON CLUSTER нужен только один раз — при создании самой Replicated базы данных. После этого он не нужен для операций внутри базы.
- Auto-created cluster:
system.clustersавтоматически показывает кластер с именем базы данных — его можно сразу использовать в Distributed table. - Рекомендуется для новых кластеров — устраняет класс ошибок, связанных с несинхронизированной схемой на репликах.