From 86d2214d7c49af627706512a5873b855e6ade6e1 Mon Sep 17 00:00:00 2001 From: Dmitry Dementiev Date: Fri, 31 Jul 2026 16:37:50 +0300 Subject: [PATCH] =?UTF-8?q?docs(adr):=20=D1=80=D0=B5=D1=88=D1=91=D0=BD=20?= =?UTF-8?q?=D1=81=D0=BE=D1=81=D1=82=D0=B0=D0=B2=20=D0=BC=D0=BE=D0=BD=D0=B8?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D0=B8=D0=BD=D0=B3=D0=B0=20=D1=81=D1=82=D0=B5?= =?UTF-8?q?=D0=BD=D0=B4=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Зачем: строчка спеки описывала только цели Prometheus, и этап 9 по ней честно сделал бы девопсовый минимум. Разбор мониторинга предшественника показал, что там из 28 панелей на вопросы дата-инженера отвечают шесть, а свежесть, доля брака и сходимость Kafka с ClickHouse не измеряются вовсе. Состав панелей решается до этапа 9: урок можно рассказать только про то, что дашборд показывает. Что: добавлен ADR 0002 — дашборды «данные», «кластер» и «запросы»; ClickHouse подключается в Grafana источником данных, панели пишутся на SQL; Prometheus сжимается до тонкого пола, сборщик метрик Airflow через StatsD не берётся. Инфраструктурные панели сохранены отдельным дашбордом: «слишком много частей» — ошибка дата-инженера, а видна она именно там. Плагин источника данных ставится сборкой своего образа Grafana, а не при старте контейнера: иначе стенд начинает зависеть от сети. Строка объёма в спеке и пункт этапа 9 указывают на ADR. Проверка: make config-test — зелено. Отсутствие источника данных ClickHouse в образе Grafana подтверждено запросом к живому стенду. Co-Authored-By: Claude Opus 5 (1M context) --- docs/adr/0002-monitoring-scope.md | 116 ++++++++++++++++++++++ docs/specs/2026-07-30-stand-v2-realism.md | 5 +- 2 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 docs/adr/0002-monitoring-scope.md diff --git a/docs/adr/0002-monitoring-scope.md b/docs/adr/0002-monitoring-scope.md new file mode 100644 index 0000000..aeb2483 --- /dev/null +++ b/docs/adr/0002-monitoring-scope.md @@ -0,0 +1,116 @@ +# ADR 0002. Что показывает мониторинг стенда + +Дата: 31 июля 2026 года. Статус: принято. + +## Решение + +Мониторинг стенда — несколько дашбордов Grafana, по одному на вопрос. Дашборд, +отвечающий на три вопроса сразу, не отвечает ни на один; отдельных файлов +не жалко. + +**«Данные»** — главный дашборд, вопросы дата-инженера: + +- свежесть: сколько прошло с момента, когда доехало последнее событие; +- поток: строк в час по источникам и как это выглядит против вчерашнего; +- брак: сколько записей ушло в таблицы `*_errors` и какая это доля; +- сходимость: сколько произвели в Kafka против того, сколько приземлилось + в ClickHouse; +- отставание чтения из Kafka; +- дневной слепок заказов: доехал ли и вовремя ли. + +Источник большинства этих панелей — не Prometheus, а сам ClickHouse: он +подключается в Grafana источником данных, панели пишутся на SQL. Метрики +дата-инженера живут в его собственных таблицах, а не в счётчиках сервисов. + +**«Кластер»** — состояние машины: процессор и память обеих нод, обращения к +дискам, части MergeTree и слияния, keeper, очередь распределённых DDL. Дашборд +кажется чужим для дата-инженера, но чужой он только на вид: «слишком много +частей» — это ошибка того, кто вставляет мелкими пачками слишком часто, а +видна она именно здесь. То же с памятью: тяжёлый `GROUP BY` без ограничения — +запрос человека, симптом — на графике памяти. + +Смотреть этот дашборд осмысленно под нагрузкой: видно, как процессор и +обращения к дискам лезут вверх на вставке и медленно оседают, когда +домержились части. Одно число «жив или нет» этому не учит, форма кривой — +учит. + +**«Запросы»** — `system.query_log` таблицей: что выполнялось, сколько заняло, +сколько памяти и строк прочитало. Здесь человек сам отвечает себе на вопрос +«почему мой дашборд в Superset тормозит». + +Системные таблицы у каждой ноды свои, поэтому панели по ним пишутся через +`clusterAllReplicas` — иначе видно половину правды. Это отдельный маленький +урок, и он нужен. + +Серверный журнал (`system.text_log`) подключается на этапе 9 вместе с runbook +«keeper упал / DDL повис в очереди»: там он и окупается. Довод за него один — +общая ось времени: в одной панели оба узла, над ней всплеск процессора, под +ней очередь DDL. `docker logs` даёт две отдельные ленты и сопоставление +руками. Издержки: журнал выключен по умолчанию, включается настройкой, таблице +нужен TTL. Если окажется дороже, чем даёт, — уходит первым. + +Prometheus остаётся, но сжимается до тонкого пола: живы ли контейнеры, не +упёрлись ли ноды в память. Он нужен, чтобы при плохой метрике данных одним +взглядом отделить «сломался конвейер» от «сломалась машина». Отдельный +сборщик метрик Kafka нужен ради отставания чтения. Сборщик метрик Airflow +через StatsD не берём. + +## Почему + +Образцом служил мониторинг предшественника: четыре дашборда, десять правил +оповещения, два внешних сборщика и урок курса. Форма там хорошая и берётся +целиком — сначала смотрим, потом ломаем одну вещь управляемым образом, видим, +как мониторинг это показал, и возвращаем назад. Содержание берётся не целиком. + +Панелей с запросами в трёх «настоящих» дашбордах предшественника — 28. +На вопрос «с данными всё в порядке?» отвечают шесть. Остальное — процессор, +память, части и слияния, размер набора DAG-файлов, время их разбора, пульс +планировщика, свободные слоты исполнителя. И при этом ни одной панели про +свежесть, ни одной про долю брака, ни одной про сходимость Kafka с ClickHouse. +То есть три главных вопроса дата-инженера там просто не заданы. + +Отсюда решение: инфраструктурные панели не убираются, а переносятся на свой +дашборд, и рядом появляется тот, которого не было. + +Три вещи предшественника не повторяем. + +Правило оповещения `Kafka No Messages Produced` краснеет на здоровом стенде, +когда живой поток просто не запущен, и уроку приходится за это извиняться +отдельным абзацем. Правило, красное в нормальном состоянии, учит не тому, что +задумано: оно учит не смотреть на оповещения. + +Самый проработанный дашборд предшественника — про генератор, которого в бою +не существует: 17 панелей с гистограммами задержек и пульсом против 12 +у ClickHouse. Силы ушли туда, где инструментировать было легко, а не туда, где +стоит вопрос. + +Три текстовые панели там хранят команды и пометку «настроено под тик +5 секунд» прямо в JSON дашборда. Поменяется тик — панель молча соврёт. +Документация живёт в документации. + +Сборщик метрик Airflow через StatsD — это отдельный контейнер плюс файл +перевода имён, и весь его выход — внутренности планировщика: пульс, слоты, +время разбора файлов. Дежурному по платформе это нужно, дата-инженеру — нет. +Вопрос «доехал ли вчерашний слепок заказов» дешевле и честнее задать самим +данным. + +## Что проверено + +31 июля 2026 года. Мониторинг предшественника разобран по файлам в +`configs/grafana/provisioning/` и `configs/prometheus.yml` репозитория +`clickstream-ch-kafka-superset-demo`: 28 панелей с запросами в дашбордах +ClickHouse, Kafka и Airflow, 17 — в дашборде генератора, 10 правил +оповещения. + +Источник данных ClickHouse — плагин, в образе Grafana его нет. Проверено +запросом к живому стенду (`/api/plugins?type=datasource`): 19 встроенных +источников, ClickHouse среди них отсутствует. Плагин ставится сборкой своего +образа Grafana, как уже собираются свои образы Airflow и Superset. Установка +при старте контейнера отвергнута: она делает `make up` зависимым от сети и от +доступности каталога плагинов, то есть стенд перестаёт подниматься по причинам, +к нему не относящимся. Версия плагина закрепляется, как закреплены остальные. + +Состав панелей выбран до этапа 9 намеренно: уроки пишутся отдельной работой +(спека, раздел 10), но рассказать урок можно только про то, что дашборд +показывает. Скопируй мы состав предшественника — урок неизбежно получился бы +про пульс планировщика. diff --git a/docs/specs/2026-07-30-stand-v2-realism.md b/docs/specs/2026-07-30-stand-v2-realism.md index f312ee0..ec621d8 100644 --- a/docs/specs/2026-07-30-stand-v2-realism.md +++ b/docs/specs/2026-07-30-stand-v2-realism.md @@ -443,7 +443,7 @@ v2 стартует пустым, поэтому объём ниже — это | Airflow | DAG'и по образцу v1: etl_pipeline (партиционная переобработка, ожидание дневного батча заказов — сенсор/Datasets), world_init/next_day, helpers | M — ~5–6 файлов | | Superset | датасеты + дашборд с тремя новыми сюжетами | M — 2 файла | | Эталонный мир | сборка артефакта v2, манифест-счётчики, чек-скрипты | M–L | -| Мониторинг | Prometheus/Grafana: цели двух нод и keeper | S — 2–4 конфига | +| Мониторинг | дашборды Grafana «данные», «кластер», «запросы»; ClickHouse источником данных, панели на SQL; Prometheus тонким полом (ADR 0002) | M — конфиги и дашборды | | Документация | доки v2 пишутся заново (см. раздел 12) | M, в тех же PR | Итого ~80–110 файлов нового репозитория (посчитаны конфиги по нодам, @@ -489,7 +489,8 @@ v2 стартует пустым, поэтому объём ниже — это 6. Расхождения B+D и опоздания; счётчики манифеста. 7. Эталонный мир: пересборка артефакта, чек-скрипты. 8. Superset-дашборд v2. -9. Мониторинг и runbook «keeper упал / DDL повис в очереди». +9. Мониторинг и runbook «keeper упал / DDL повис в очереди». Состав дашбордов + и границы — ADR 0002. Критерий приёмки этапа — честный: `make up` работает и проходят smoke-проверки, а не «дашборд зелёный». Это минимальная планка; свои