Кластер: где живёт опыт менти и какая топология #14
Notifications
Due Date
No due date set.
Blocks
Depends on
#17 Собрать спеку боевого реализма
ddmitry/clickstream-ch-kafka-superset-demo
#12 Ресурсный бюджет стенда на 16 ГБ
ddmitry/clickstream-ch-kafka-superset-demo
#13 Цена кластера для пайплайна
ddmitry/clickstream-ch-kafka-superset-demo
#18 Модель данных: широкое событие и второй источник
ddmitry/clickstream-ch-kafka-superset-demo
Reference: ddmitry/clickstream-ch-kafka-superset-demo#14
Reference in New Issue
Block a user
Part of #10
Question
Где менти получает кластерный опыт ClickHouse и в какой топологии.
Рабочая гипотеза владельца (Notes карты #10): кластер в этом стенде,
облегчённо — 2 шарда без реплик; цель — Distributed и ON CLUSTER на
живом потоке («голый» clickhouse-learning-cluster этого не даёт).
Решить: топология (2×1 против 2×2 — ресурсный бюджет в #12),
опциональность (
make up-cluster, не дефолт — рекомендация #13),ключ шардирования широкого события (гипотеза из #18:
click_id),что кластер делает с трансформациями (JOIN поверх Distributed,
TRUNCATE — боли из #13) и с эталонным миром.
ddmitry referenced this issue2026-07-26 21:39:19 +03:00
Резолюция: кластер живёт в стенде, 2×1, единственным режимом
Где опыт. Кластерный опыт менти получает в этом стенде, на живом потоке. Соседний learning-cluster остаётся разминкой при курсе: там концепции, здесь — жизнь (забыть ON CLUSTER, получить ошибку, починить). Исполнение — в v2-репозитории.
Режим — единственный. Кластер нельзя выключить:
make upподнимает сразу кластер. Рекомендация #13 «опциональный make up-cluster с шаблонизацией SQL» пересмотрена и отклонена: двойное сопровождение SQL дороже пользы, и это рифмуется с решением #18 «модель одна, целевая». Погружение работает, только когда лёгкого выхода нет; страховка от «слишком сложно» — не выключатель, а отсутствие реплик и runbook.Топология: 2 шарда × 1 реплика + отдельный clickhouse-keeper.
{shard}/{replica}и путей keeper; готовность к будущей реплике).Ключ шардирования. События — clientID: строго поглощает гипотезу click_id (сессия лежит внутри посетителя), делает локальными сессионизацию, будущую склейку идентичностей (#16) и uniq-метрики; у анонимов кука есть — NULL-перекоса нет. Точное имя поля решит спека #17. Заказы —
hash(order_id), сверка purchase против заказа — через GLOBAL JOIN (заказы малы, это легитимная витрина для GLOBAL). Анти-паттерны (rand(), toDate) — в лекцию как отрицательные примеры.Приём из Kafka. Kafka-таблицы и MV — на обеих нодах, одна consumer group, 2 партиции на топик; MV пишут в Distributed-цели. Раскладку решает ключ, а не брокер: события — по clientID, сырьё — по
cityHash64(сырой строки). Урок: «кто консьюмил — меняется между прогонами, куда легли данные — нет»; лабная сцена — разные группы → дубли.Трансформации. Конвейер v2 — без TRUNCATE как рабочего паттерна: поток — append-only в ReplacingMergeTree (дедуп через argMax), батчевая переобработка — по дневным партициям (
DROP/REPLACE PARTITION ON CLUSTER).TRUNCATE ... ON CLUSTERостаётся только вmake reset. Политика джойнов: по ключу со-локации — обычный джойн с комментарием, почему локальный результат корректен; по любому другому ключу — только явный GLOBAL;NOT IN— только GLOBAL NOT IN.Эталонный мир. Все контрольные суммы и сверки — только по Distributed-таблицам (агрегаты от раскладки не зависят); раскладка по шардам нигде не фиксируется, пошардовые наблюдения — исследовательские, в лабах.
Передаётся в спеку #17: точный состав/имя ключевого поля; механика партиционной переобработки (границы дня, поздние данные); эмпирическая проверка поведения джойна двух Distributed (
distributed_product_mode); runbook «keeper упал / DDL повис в очереди» в troubleshooting.