- Зачем:
- второй круг ревью нашёл, что текст спорит с собственной приёмкой: окно
держалось доводом «слияния за минуту-две», а замер даёт двадцать секунд;
довод панели ошибок опирался на отказ по памяти, которого ADR 0004 на этом
стенде не обещает.
- Что:
- «Части» сортируются по таблице: сортировка по числу частей разводила две
ноды одной таблицы, как только между ними вставала чужая.
- у «Слияний» столбик шириной в минуту, иначе редкие события выходили
волосяной линией; из заголовка убран «слой» — фильтр отсекает журналы
сервера, а не выбирает слои.
- в cluster.md исправлены довод за окно, ложное «времени в system.parts нет»,
счёт панелей без нод (их две, не одна) и разрешение, в котором снят замер
процессора.
- панель ошибок и её запись в ADR 0002 переписаны под проверенное: отказ на
шарде воспроизведён принудительным пределом памяти.
- из queries.md убран абзац про SELECT 1 — он объяснял пол удалённой панели.
- Проверка:
- make config-test; make smoke 21/21; make check-clickhouse 10/10.
- все десять панелей отвечают через /api/ds/query в окнах на полчаса, час и
шесть часов; шаг столбика слияний проверен отдельным запросом.
144 lines
12 KiB
Markdown
144 lines
12 KiB
Markdown
# 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), но рассказать урок можно только про то, что дашборд
|
||
показывает. Скопируй мы состав предшественника — урок неизбежно получился бы
|
||
про пульс планировщика.
|
||
|
||
21 августа 2026 года дашборд «Данные» собран. Один пункт решения исполнен не
|
||
буквально: у панели потока нет ряда «против вчерашнего». Сдвинуть ряд на
|
||
модельные сутки значит записать ускорение мира в JSON дашборда — ровно ту
|
||
пометку, от которой этот же ADR отговаривает выше, — а реальные сутки на стенде
|
||
не с чем сравнивать. Довод целиком и остальное устройство дашборда —
|
||
[docs/architecture/monitoring/data.md](../architecture/monitoring/data.md).
|
||
|
||
Тогда же собраны «Кластер» и «Запросы». Довод про `clusterAllReplicas`
|
||
подтвердился с одной поправкой: очередь распределённых DDL лежит не у ноды, а в
|
||
keeper, и обе ноды читают её целиком — запрос вернул с каждой одни и те же 124
|
||
записи. Обёртка там не добавила бы правды, а удвоила бы каждую строку, поэтому
|
||
единственная панель «Кластера» без неё — эта. Keeper своих системных таблиц не
|
||
имеет вовсе, и панель по нему приходит из Prometheus.
|
||
|
||
«Запросы» получили на две панели больше, чем сказано выше. Разбор запросов по
|
||
посетителям продиктован [ADR 0007](0007-clickhouse-access.md): своя учётка
|
||
Grafana заведена там ровно затем, чтобы её запросы были отличимы от
|
||
человеческих.
|
||
Отдельная панель ошибок понадобилась потому, что отказ достаётся шарду: в
|
||
замере с принудительным пределом памяти каждая нода записала свой, и строка
|
||
шарда видна только без фильтра по инициатору. Здешний сюжет про тяжёлый
|
||
`GROUP BY` при этом кончается не отказом, а сбросом на диск
|
||
([ADR 0004](0004-resource-limits.md)) — отказ на стенде приходится вызывать
|
||
настройкой. Устройство обоих дашбордов —
|
||
[cluster.md](../architecture/monitoring/cluster.md) и
|
||
[queries.md](../architecture/monitoring/queries.md).
|