- Зачем:
- справочники читает человек со стороны, а «пульт мира», «опись мира»,
«работник» и «сырьё» звучали шуткой или калькой времён разработки
(тикет #214, выбор владельца).
- Что:
- CONTEXT.md: статьи «Паспорт мира», «Даги модельного времени»,
«Шаговый даг», «Сырые данные», старые слова в строках «Избегать»;
пометки в ADR 0005, 0008, 0009 без переписывания решений.
- замены по README, справочникам, путеводителю, лабам, спекам,
комментариям дагов и SQL, тегу дага и панели Grafana; имена в коде
не тронуты.
- world.md и stand.md: 35 находок вычитки внесены, регистр выровнен.
- Проверка:
- make config-test; make lint в корне и в generator/; make test в
generator/ (437 passed); скрипт ссылок из #212 пуст; grep старых
слов вне ADR, research и CONTEXT.md пуст.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QBCtU38qSHg5DvgtnKXcW
118 lines
10 KiB
Markdown
118 lines
10 KiB
Markdown
# Дашборд «Данные»
|
||
|
||
`infra/grafana/provisioning/dashboards/data.json` — шесть панелей на один
|
||
экран. Вопрос у экрана один: с потоком всё в порядке? Состав панелей и довод за
|
||
каждую — [ADR 0002](../../adr/0002-monitoring-scope.md).
|
||
|
||
Свой вопрос каждая панель называет заголовком прямо на экране. Здесь — только
|
||
источники, о них и речь ниже.
|
||
|
||
| Панель | Откуда берёт |
|
||
|---|---|
|
||
| Свежесть | `ods.event_dist`, `ods.order_dist` |
|
||
| Поток | `stg.hits_raw_dist`, `stg.orders_raw_dist` |
|
||
| Брак | те же и `ods.*_errors_dist` |
|
||
| Сходимость | экспортёр Kafka и `stg.hits_raw_dist` |
|
||
| Отставание | `kafka_consumergroup_lag` |
|
||
| Дневной слепок | `stg.orders_raw_dist` |
|
||
|
||
## Почему слои у панелей разные
|
||
|
||
Свежесть спрашивают у ODS. Это слой, который читают, и у заказов дорога до него
|
||
длиннее: в STG данные привозит забор, а типизированную строку кладёт разбор.
|
||
Встань разбор — свежесть ODS это покажет, а свежесть STG — нет.
|
||
|
||
Читает свежесть физическую `_dist`, а не каноническое `ods.*_v`. Представление
|
||
прячет за собой `FINAL` и отвечает про текущее состояние сущностей, а вопрос
|
||
здесь про доставку. Местом диагностики доставленных версий физическая таблица
|
||
названа там же, где заведено представление (`sql/ddl/30-ods-views.sql`).
|
||
|
||
Поток и брак считаются по сырому слою. Он хранит каждую доставку и ничего не
|
||
схлопывает, а `ReplacingMergeTree` в ODS схлопнет и повтор доставки события, и
|
||
все версии одного заказа. Считай мы поток по ODS — он занизился бы, и тем
|
||
сильнее, чем дольше живёт стенд.
|
||
|
||
Доля брака берётся от приехавшего, а не от суммы «годные плюс брак»: брак не
|
||
отдельная куча, а часть сырых данных, которая не прошла разбор.
|
||
|
||
Окно у панели брака — окно дашборда, и это не косметика. Сырые данные живут трое
|
||
суток, а брак — месяц: доля за всё время делила бы месяц брака на трое суток
|
||
приехавшего и однажды перевалила бы за сотню процентов.
|
||
|
||
Панель дневного слепка, наоборот, окна не знает. Её вопрос про состояние, а не
|
||
про отрезок, и последние десять слепков она показывает всегда.
|
||
|
||
Отдельного ряда «против вчерашнего» на панели потока нет, и это решение, а не
|
||
пропуск. Реальное «вчера» на стенде чаще всего приходится на время, когда
|
||
стенда ещё не было. А сдвинуть ряд на модельные сутки значит записать в JSON
|
||
дашборда ускорение мира — ровно ту пометку про тик, которую [ADR
|
||
0002](../../adr/0002-monitoring-scope.md) в дашборде держать не велит: поменяют
|
||
ускорение, и панель молча соврёт. Сравнение остаётся глазу: модельные сутки
|
||
укладываются в минуты реального времени, и соседние дни мира помещаются в одно
|
||
окно панели сами.
|
||
|
||
## Приземлившееся считают в сыром слое
|
||
|
||
Приземлившееся панели считают по `stg.*_raw_dist`, произведённое — по метрикам
|
||
экспортёра. Таблицы движка Kafka `stg.hits_raw_kafka` и `stg.orders_raw_kafka`
|
||
хранилищем не работают: у второго стоит `kafka_commit_on_select`
|
||
(`sql/ddl/10-stg-tables.sql`), и запрос из панели забрал бы слепок себе,
|
||
сдвинул офсеты, а даг приёма приехал бы к пустому топику.
|
||
|
||
## Как считается сходимость
|
||
|
||
Произведённое живёт в Kafka, приземлившееся — в ClickHouse, и со своей стороны
|
||
ни одна из них не видит другую. Поэтому панель смешанная: ряд «произведено в
|
||
Kafka» приходит из Prometheus, ряд «приземлилось в ClickHouse» — из ClickHouse.
|
||
Единицы общие: сообщения за интервал панели. Со стороны Kafka это разность
|
||
офсетов топика, «сейчас минус интервал назад», с суммой по обеим партициям; со
|
||
стороны ClickHouse — `count()` строк STG по тому же интервалу.
|
||
|
||
Два соседних способа отвергнуты, и оба по замеру на живом стенде. `increase`
|
||
растягивает приращение на всё окно и на минутном интервале промахивается на
|
||
проценты: здоровый стенд выглядел бы расходящимся. Накопленный итог от начала
|
||
окна точнее обоих приростов, но отсчитывать его надо от края окна — а на
|
||
свежем стенде окно начинается раньше, чем появился экспортёр, и ряд пропадает
|
||
целиком.
|
||
|
||
Столбцы ClickHouse подписаны правым краем, а не левым. Точка Prometheus — это
|
||
прирост к моменту времени, а `count()` по интервалу — сумма, которая набирается
|
||
к его концу; подпиши мы её началом, здоровые ряды разъехались бы ровно на один
|
||
столбец. Шаг панели при этом не мельче минуты: экспортёр опрашивают раз в
|
||
пятнадцать секунд, и на более мелком шаге ряд Kafka пошёл бы ступеньками там,
|
||
где ряд ClickHouse идёт гладко.
|
||
|
||
Точка в точку ряды всё равно не совпадут, и ждать этого не надо: опрос
|
||
экспортёра не попадает на границы столбцов, поэтому на разгоне потока линия
|
||
Kafka идёт чуть выше. Читать надо устойчивый разрыв между линиями; разница в
|
||
один столбец не значит ничего.
|
||
|
||
Панель смотрит на топик событий. У него приём непрерывный, и разрыв виден сразу.
|
||
Слепок заказов уезжает пачкой раз в модельные сутки, и вопрос к нему другой — не
|
||
«сходится ли поток», а «доехала ли выгрузка и вовремя ли». На него отвечает своя
|
||
панель, и модельный день она берёт из самого сообщения: в STG он приезжает полем
|
||
`snapshot_date`.
|
||
|
||
## Что проверено
|
||
|
||
Дашборд проверен на живом стенде 21 августа 2026 года, `world_live` снят с
|
||
паузы.
|
||
|
||
- Дашборд поднимается из каталога сам: файл положен, панели появились без
|
||
ручного импорта. Сохранение и удаление через API отвергнуты («Cannot save
|
||
provisioned dashboard», «provisioned dashboard cannot be deleted»).
|
||
- Все шесть панелей отвечают через `/api/ds/query` — и в окне часа по
|
||
умолчанию, и в окне на шесть часов, которое начинается раньше, чем поднялся
|
||
экспортёр. Пустых нет ни при идущем потоке, ни при остановленном.
|
||
- Брак: подсунутое в топик `hits` негодное сообщение легло в
|
||
`ods.event_errors` с классом `keyset_mismatch`; панель показала единицу и
|
||
долю 0,039 % в десятиминутном окне. Строка убрана мутациями из
|
||
`stg.hits_raw_rep` и `ods.event_errors_rep`, обе таблицы вернулись к нулю.
|
||
- Сходимость: на живом потоке за двадцать пять минут медиана расхождения между
|
||
рядами 3 %, худший столбец 11 % — на переломе потока, как и описано выше.
|
||
- Свежесть реагирует на остановленный поток и возвращается. Через пять минут
|
||
после конца модельного дня панель показала 305 с у событий и 288 с у
|
||
заказов; стоило пустить следующий день, события вернулись к секунде.
|
||
Свежесть заказов при этом растёт до конца дня и садится, когда доедет его
|
||
слепок, — так и устроен второй источник.
|