Analytics service
В сервисе используются три варианта схемы в зависимости от топологии ClickHouse:
- Non-sharded — один standalone ClickHouse без репликации.
- Replicated Non-sharder —
1 shard x 2 replicas. - Sharded —
N shards x M replicas.
Важно: в ClickHouse репликация и шардирование — это разные механизмы. Репликация работает на уровне конкретной таблицы, а не всего сервера; шардирование отвечает за распределение данных между разными шардами.
Во всех схемах базовый смысл такой - таблицы представляют собой набор событий произошедших в системе и
допускают повторную доставку одних и тех же событий. ReplacingMergeTree умеет удалять дубликаты с одинаковым
ORDER BY ключом во время фоновых merge-операций.
При этом дедупликация происходит не сразу, а только со временем, поэтому этот движок подходит именно для “очистки
дублей”.
Так как в наших ORDER BY включён sequenceId, здесь ReplacingMergeTree по сути работает как защита от повторной
записи одного и того же события, а не как хранение “последнего состояния платежа”. Это уже следует из самой схемы:
если sequenceId меняется, для ClickHouse это уже другая строка.
Для standalone-конфигурации используются обычные таблицы на ReplacingMergeTree.
Почему может быть выгодно:
- это самый простой вариант без Keeper / ZooKeeper и без межнодовой координации;
- все данные лежат локально на одном узле;
- нет накладных расходов на репликацию;
- подходит, когда нужен один инстанс ClickHouse без HA.
Плюсы:
- минимальная сложность эксплуатации;
- меньше инфраструктурных зависимостей;
- хороший выбор для dev / test / небольших инсталляций.
Минусы:
- нет отказоустойчивости на уровне ClickHouse;
- потеря узла = потеря доступа к данным, пока узел не восстановлен.
Для конфигурации 1 shard x 2 replicas используются таблицы на ReplicatedReplacingMergeTree.
Почему может быть выгодно:
- шард остаётся один, то есть логически набор данных не делится;
- выше отказоустойчивость, данные хранятся на одном хосте. ClickHouse Keeper / ZooKeeper хранит метаданные репликации, а
INSERTиALTERреплицируются между репликами.
Плюсы:
- высокая доступность;
- можно пережить падение одной реплики;
- удобно для zero-downtime обслуживания и обновлений.
Минусы:
- инфраструктура сложнее и дороже, чем standalone;
Для конфигурации N shards x M replicas используются две таблицы на каждую сущность:
- локальная таблица
*_localнаReplicatedReplacingMergeTree; - распределённая таблица без хранения данных на
Distributed, которая маршрутизируетINSERT/SELECTпо кластеру.
Distributed-таблица позволяет работать с кластером как с одной логической таблицей, а реальные данные лежат в _local на конкретном хосте. Для replicated local-таблиц обычно требуется internal_replication=true в конфигурации кластера: тогда запись идёт в одну healthy-реплику шарда, а дальше уже распространяется механизмом репликации. Это рекомендуемый режим для Distributed поверх Replicated таблиц.
Плюсы:
- горизонтальное масштабирование по объёму данных и нагрузке;
- отказоустойчивость внутри каждого шарда;
Минусы:
- самая сложная схема в эксплуатации;
- нужно аккуратно выбирать sharding key;
- появляется больше межнодовых сетевых операций. Запросы и вставки чаще требуют межсерверного обмена: координатор рассылает запросы по шардам, собирает и доагрегирует результаты, а при записи данные могут дополнительно пересылаться на нужный shard. Это даёт горизонтальное масштабирование, но повышает latency, сетевой трафик и чувствительность к медленным/недоступным узлам
- Standalone / dev / маленькая инсталляция → ReplacingMergeTree
- Нужен HA, но объём пока помещается в один shard → ReplicatedReplacingMergeTree
- Нужно масштабирование по данным и нагрузке → ReplicatedReplacingMergeTree + Distributed
Если кластер физически поднят как 1 shard x 2 replicas, но на нём создана схема с обычным ReplacingMergeTree, то репликации данных не будет, даже если Keeper/ZooKeeper в инфраструктуре присутствует. Репликация в ClickHouse включается не на уровне кластера вцелом, а выбором Replicated*-движка у конкретной таблицы.
То есть в таком случае на двух узлах будут две независимые локальные таблицы. Запросы могут попадать то на один, то на другой хост, результаты могут отличаться просто потому, что это не master/slave-пара, а два разных источника данных.
В ClickHouse нет модели “один master для чтения и записи, остальные standby”. Для replicated-таблиц используется асинхронная multi-master репликация: писать и читать можно с любой доступной реплики, а остальные реплики подтягивают изменения в фоне.
Для distributed-запросов ClickHouse выбирает одну реплику из каждого шарда; выбор зависит от стратегии балансировки ( load_balancing). По умолчанию используется random, также есть round_robin, nearest_hostname, first_or_random и другие стратегии. Если у реплик разные данные, запросы действительно могут возвращать разные результаты.