Кластер: где живёт опыт менти и какая топология #14

Closed
opened 2026-07-26 21:39:16 +03:00 by ddmitry · 1 comment
Owner

Part of #10

⚠ Тело восстановлено по памяти при переносе с GitHub (аккаунт
заблокирован 2026-07-26); оригинал не сохранился. Блокировки — точные,
из снимка нативных dependencies.

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) и с эталонным миром.

Part of #10 > ⚠ Тело восстановлено по памяти при переносе с GitHub (аккаунт > заблокирован 2026-07-26); оригинал не сохранился. Блокировки — точные, > из снимка нативных dependencies. ## 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 added the wayfinder:grilling label 2026-07-26 21:39:16 +03:00
ddmitry added a new dependency 2026-07-29 20:38:23 +03:00
ddmitry added a new dependency 2026-07-29 20:40:29 +03:00
ddmitry added a new dependency 2026-07-29 20:40:29 +03:00
ddmitry self-assigned this 2026-07-29 21:54:28 +03:00
Author
Owner

Резолюция: кластер живёт в стенде, 2×1, единственным режимом

Где опыт. Кластерный опыт менти получает в этом стенде, на живом потоке. Соседний learning-cluster остаётся разминкой при курсе: там концепции, здесь — жизнь (забыть ON CLUSTER, получить ошибку, починить). Исполнение — в v2-репозитории.

Режим — единственный. Кластер нельзя выключить: make up поднимает сразу кластер. Рекомендация #13 «опциональный make up-cluster с шаблонизацией SQL» пересмотрена и отклонена: двойное сопровождение SQL дороже пользы, и это рифмуется с решением #18 «модель одна, целевая». Погружение работает, только когда лёгкого выхода нет; страховка от «слишком сложно» — не выключатель, а отсутствие реплик и runbook.

Топология: 2 шарда × 1 реплика + отдельный clickhouse-keeper.

  • Движки локальных таблиц — Replicated* (опыт макросов {shard}/{replica} и путей keeper; готовность к будущей реплике).
  • Без HAProxy: без реплик балансировать нечего, менти видел его в learning-cluster; в доках — абзац «в бою здесь LB».
  • Роли нод: нода 1 — инициатор DDL и подключение Airflow; Superset — на ноду 2. Это осознанная ловушка правильных ошибок: забытый ON CLUSTER или VIEW поверх локальной таблицы проявляются в дашборде сами.
  • Репликационную эксплуатацию (2×2) не берём: отдельный операционный домен, затмит остальное; в лекцию — вставка «как топологии выбирают в бою: часто 1 шард × N реплик, шардирование — про рост».

Ключ шардирования. События — 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.

## Резолюция: кластер живёт в стенде, 2×1, единственным режимом **Где опыт.** Кластерный опыт менти получает в этом стенде, на живом потоке. Соседний learning-cluster остаётся разминкой при курсе: там концепции, здесь — жизнь (забыть ON CLUSTER, получить ошибку, починить). Исполнение — в v2-репозитории. **Режим — единственный.** Кластер нельзя выключить: `make up` поднимает сразу кластер. Рекомендация #13 «опциональный make up-cluster с шаблонизацией SQL» пересмотрена и отклонена: двойное сопровождение SQL дороже пользы, и это рифмуется с решением #18 «модель одна, целевая». Погружение работает, только когда лёгкого выхода нет; страховка от «слишком сложно» — не выключатель, а отсутствие реплик и runbook. **Топология: 2 шарда × 1 реплика + отдельный clickhouse-keeper.** - Движки локальных таблиц — Replicated* (опыт макросов `{shard}/{replica}` и путей keeper; готовность к будущей реплике). - Без HAProxy: без реплик балансировать нечего, менти видел его в learning-cluster; в доках — абзац «в бою здесь LB». - Роли нод: нода 1 — инициатор DDL и подключение Airflow; **Superset — на ноду 2**. Это осознанная ловушка правильных ошибок: забытый ON CLUSTER или VIEW поверх локальной таблицы проявляются в дашборде сами. - Репликационную *эксплуатацию* (2×2) не берём: отдельный операционный домен, затмит остальное; в лекцию — вставка «как топологии выбирают в бою: часто 1 шард × N реплик, шардирование — про рост». **Ключ шардирования.** События — **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.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Blocks
#17 Собрать спеку боевого реализма
ddmitry/clickstream-ch-kafka-superset-demo
Depends on
Reference: ddmitry/clickstream-ch-kafka-superset-demo#14