fix(stand): снят несуществующий бюджет памяти, нодам ClickHouse — 4 ГиБ #25
@@ -13,7 +13,15 @@ Prometheus, Grafana и общая база Postgres для метаданных.
|
|||||||
|
|
||||||
## Быстрый старт
|
## Быстрый старт
|
||||||
|
|
||||||
Нужны Docker с Compose. Полная проверка также использует `curl`, `jq`, `awk`,
|
Нужны Docker с Compose и около 8 ГБ памяти, доступной Docker. Это не объём
|
||||||
|
ноутбука, а то, что отдано самому Docker: в Docker Desktop и WSL2 он живёт
|
||||||
|
внутри виртуальной машины и получает лишь часть памяти хозяина. Сколько выдано
|
||||||
|
сейчас, в байтах, покажет `docker info --format '{{.MemTotal}}'`. В WSL2 это
|
||||||
|
поднимается параметром `memory` в файле `.wslconfig` домашнего каталога
|
||||||
|
пользователя Windows; после правки нужен `wsl --shutdown`. Если своей машины не
|
||||||
|
хватает, стенд одинаково хорошо живёт на недорогом VPS.
|
||||||
|
|
||||||
|
Полная проверка также использует `curl`, `jq`, `awk`,
|
||||||
`grep`, `sed`, `tail`, `sleep` и `timeout`. По умолчанию должны быть свободны
|
`grep`, `sed`, `tail`, `sleep` и `timeout`. По умолчанию должны быть свободны
|
||||||
порты `23000`, `28080`, `28088`, `28123`, `28124`, `29000`, `29001`, `29090`
|
порты `23000`, `28080`, `28088`, `28123`, `28124`, `29000`, `29001`, `29090`
|
||||||
и `29092`. Для статической проверки `make config-test` нужен `uv`.
|
и `29092`. Для статической проверки `make config-test` нужен `uv`.
|
||||||
@@ -51,8 +59,10 @@ Superset, создаёт администратора и импортирует
|
|||||||
и `test_kafka`, метаданные и подключение Superset. Первый пробник создаёт
|
и `test_kafka`, метаданные и подключение Superset. Первый пробник создаёт
|
||||||
таблицы на обеих нодах и читает через `Distributed` на ноде 2 строку из
|
таблицы на обеих нодах и читает через `Distributed` на ноде 2 строку из
|
||||||
локальной таблицы ноды 1. Второй пишет в Kafka и читает свой маркер. В конце
|
локальной таблицы ноды 1. Второй пишет в Kafka и читает свой маркер. В конце
|
||||||
проверка ждёт 20 секунд покоя, печатает общую память контейнеров и падает при
|
проверка спрашивает у Docker, не убивало ли ядро что-нибудь в долгоживущих
|
||||||
превышении 3,4 ГБ. Временный топик проверки с машины и запуски DAG удаляются;
|
контейнерах за нехватку памяти и не включалась ли политика перезапуска: убитый
|
||||||
|
контейнер Docker поднимает сам, и проверка состояния об этом промолчит.
|
||||||
|
Временный топик проверки с машины и запуски DAG удаляются;
|
||||||
постоянный топик пробника сохраняется, а старые записи чистит Kafka.
|
постоянный топик пробника сохраняется, а старые записи чистит Kafka.
|
||||||
|
|
||||||
`make smoke-cluster` запускает отдельную глубокую проверку ClickHouse: описание
|
`make smoke-cluster` запускает отдельную глубокую проверку ClickHouse: описание
|
||||||
|
|||||||
+2
-1
@@ -15,7 +15,8 @@ x-clickhouse-common: &clickhouse-common
|
|||||||
clickhouse-keeper:
|
clickhouse-keeper:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
ulimits: *clickhouse-nofile
|
ulimits: *clickhouse-nofile
|
||||||
mem_limit: 1g
|
# Гигабайта не хватало: половину съедали страницы самого бинарника (ADR 0004).
|
||||||
|
mem_limit: 4g
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "clickhouse-client --host 127.0.0.1 --query 'SELECT 1' >/dev/null 2>&1"]
|
test: ["CMD-SHELL", "clickhouse-client --host 127.0.0.1 --query 'SELECT 1' >/dev/null 2>&1"]
|
||||||
interval: 5s
|
interval: 5s
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# ADR 0001. Сервисы каркаса стенда
|
# ADR 0001. Сервисы каркаса стенда
|
||||||
|
|
||||||
Дата: 30 июля 2026 года. Статус: принято.
|
Дата: 30 июля 2026 года. Статус: принято; ресурсный довод отозван
|
||||||
|
[ADR 0004](0004-resource-limits.md).
|
||||||
|
|
||||||
## Решение
|
## Решение
|
||||||
|
|
||||||
@@ -50,6 +51,13 @@ Prometheus читает встроенные точки метрик двух с
|
|||||||
компьютера. Отказ от triggerer, второго Postgres и внешних сборщиков удерживает
|
компьютера. Отказ от triggerer, второго Postgres и внешних сборщиков удерживает
|
||||||
стенд в пределе 3,4 ГБ.
|
стенд в пределе 3,4 ГБ.
|
||||||
|
|
||||||
|
Ресурсный довод предыдущего абзаца отозван
|
||||||
|
[ADR 0004](0004-resource-limits.md): предела 3,4 ГБ у стенда нет, вместо него
|
||||||
|
объявлено требование к машине. Сами решения остаются в силе по остальным
|
||||||
|
основаниям, названным выше. Отказ от внешних сборщиков вдобавок частично
|
||||||
|
пересмотрен [ADR 0002](0002-monitoring-scope.md): сборщик метрик Kafka нужен
|
||||||
|
ради отставания чтения.
|
||||||
|
|
||||||
Тома `clickhouse_*_data` хранят данные keeper и двух нод ClickHouse.
|
Тома `clickhouse_*_data` хранят данные keeper и двух нод ClickHouse.
|
||||||
`kafka_data`, `postgres_metadata_data`, `superset_home`, `prometheus_data` и
|
`kafka_data`, `postgres_metadata_data`, `superset_home`, `prometheus_data` и
|
||||||
`grafana_data` хранят состояние своих сервисов. `airflow_logs` хранит журналы,
|
`grafana_data` хранят состояние своих сервисов. `airflow_logs` хранит журналы,
|
||||||
|
|||||||
@@ -0,0 +1,153 @@
|
|||||||
|
# ADR 0004. Ограничения ресурсов на стенде
|
||||||
|
|
||||||
|
Дата: 1 августа 2026 года. Статус: принято.
|
||||||
|
|
||||||
|
## Решение
|
||||||
|
|
||||||
|
Общего бюджета памяти у стенда нет. Вместо предела — требование к машине:
|
||||||
|
стенду нужно около 8 ГБ памяти, доступной Docker. Это не объём ноутбука, а то,
|
||||||
|
что отдано докеру: в WSL2 величина задаётся файлом `.wslconfig`, и по умолчанию
|
||||||
|
она меньше. Кому своей машины не хватает — берёт недорогой VPS. README
|
||||||
|
объясняет это менти словами.
|
||||||
|
|
||||||
|
Проверка суммарного потребления памяти уходит из `scripts/stand-smoke.sh`.
|
||||||
|
Вместе с ней уходят зависящая от её сообщения проверка в `tests/docs-guards.sh`
|
||||||
|
и описание порога в README. Взамен `make smoke` спрашивает у Docker, не убивало
|
||||||
|
ли ядро что-нибудь в долгоживущих контейнерах за нехватку памяти и не включалась
|
||||||
|
ли политика перезапуска. Прежний бюджет она не заменяет: числа, с которым
|
||||||
|
что-то сравнивают, у неё нет вовсе — ответ либо «убивало», либо «нет».
|
||||||
|
|
||||||
|
Нодам ClickHouse — по 4 ГиБ вместо гигабайта. Дальше в этом тексте предел
|
||||||
|
памяти контейнера (`mem_limit`) называется коробкой: сервер живёт внутри неё и
|
||||||
|
о самой машине ничего не знает. Остальные `mem_limit` не меняются.
|
||||||
|
|
||||||
|
Числа, выставленные ради прежнего бюджета, остаются в силе, но лишаются
|
||||||
|
статуса решения: `KAFKA_HEAP_OPTS`, `shared_buffers`, `max_connections`,
|
||||||
|
`AIRFLOW__CORE__PARALLELISM` и девять неизменённых `mem_limit`. Основания,
|
||||||
|
кроме отменённого, у них нет. Кто в них упрётся — меняет по первому
|
||||||
|
свидетельству и этот ADR не пересматривает. Срок хранения метрик Prometheus
|
||||||
|
сюда не входит: неделя истории — осознанный учебный выбор, и цена у него
|
||||||
|
дисковая.
|
||||||
|
|
||||||
|
Ресурсный довод ADR 0001 отозван.
|
||||||
|
|
||||||
|
## Почему
|
||||||
|
|
||||||
|
Предел 3,4 ГБ никто не выдавал. Число появилось в спеке «Боевой реализм стенда
|
||||||
|
(v2)», раздел «Ресурсный бюджет», как оценка расхода, посчитанная по
|
||||||
|
стенду-предшественнику — до того как v2 впервые собрали. Оттуда оно попало
|
||||||
|
жёстким порогом в `make smoke`, `make smoke` стал критерием приёмки каждого
|
||||||
|
этапа, а дальше решения сверялись уже с порогом, а не с исходным доводом. Так
|
||||||
|
экономия памяти стала ценностью, которую никто не выбирал.
|
||||||
|
|
||||||
|
Проверка суммы меряет не то, что называет. На cgroup v2 `docker stats`
|
||||||
|
показывает `memory.current` за вычетом неактивных файловых страниц, то есть
|
||||||
|
вместе с активным страничным кэшем. На праздном контейнере это 1056 МБ, из
|
||||||
|
которых 779 МБ файловых при 234 МБ анонимных. Сумма отвечает на вопрос
|
||||||
|
«сколько файлов стенд потрогал», а не «сколько памяти ему нужно». Как только
|
||||||
|
на этапе 2 появятся настоящие данные, порог будет перейден одним страничным
|
||||||
|
кэшем, и проверка начнёт краснеть на здоровом стенде. Правило, красное в
|
||||||
|
норме, учит не смотреть на оповещения — это уже записано в ADR 0002. Настоящую
|
||||||
|
аварию она к тому же не ловила: 31 июля нода отказала запросу по памяти внутри
|
||||||
|
своей коробки, сумма при этом была в норме — 3181 МиБ из 3242,5, — а красным
|
||||||
|
стенд сделал пробник. Механизм оповещения работает и без неё.
|
||||||
|
|
||||||
|
Новая проверка — не тот же бюджет под другим именем. Она закрывает другую дыру:
|
||||||
|
убитый за память контейнер Docker поднимает сам, через полминуты его проверка
|
||||||
|
состояния снова зелёная, и `make smoke` докладывает, что всё хорошо — хотя нода
|
||||||
|
умирала и потеряла всё, что держала в памяти. Проверка спрашивает у Docker
|
||||||
|
факт, а не величину, поэтому её нечего подгонять и незачем пересматривать,
|
||||||
|
когда стенд растёт.
|
||||||
|
|
||||||
|
Гигабайт на ноду был неработоспособен, и причина не та, что предполагал
|
||||||
|
issue #21. У праздной ноды около 530 МиБ RSS — это страницы её собственного
|
||||||
|
бинарника: файл `clickhouse` весит 790 МБ, ядро подгружает куски по мере
|
||||||
|
обращения к ним, а отказ по превышению памяти сравнивается с RSS, куда такие
|
||||||
|
страницы входят. Учёта сервера в них почти нет: `MemoryTracking` при этом
|
||||||
|
всего 113 МиБ. Это постоянная часть расхода: меньше неё нода не занимает
|
||||||
|
никогда. Из гигабайта на саму работу оставалось около 350 МиБ.
|
||||||
|
|
||||||
|
Дальше нода набирает рабочую память, и вместе с постоянной частью та перестаёт
|
||||||
|
помещаться. За обычную сессию стенда замерено: страницы бинарника 523 → 531
|
||||||
|
МиБ, то есть стоят на месте, а рабочая память 489 → 723 МиБ. Инцидент 31 июля
|
||||||
|
имел ту же форму — 531 → 774 МиБ: та же постоянная часть плюс наросшая работа.
|
||||||
|
Рестарт возвращал число назад, и это выглядело как утечка. Отчего именно растёт
|
||||||
|
рабочая память, здесь не разбирается — для решения хватает того, что одна
|
||||||
|
только постоянная часть занимала больше половины коробки. Заводские кэши тут
|
||||||
|
ни при чём: в коробке на гигабайт
|
||||||
|
ClickHouse сам понижает каждый до 512 МиБ, а на стенде без данных они и вовсе
|
||||||
|
пусты.
|
||||||
|
|
||||||
|
Для ClickHouse коробка — не просто верхняя граница: сервер настраивает себя по
|
||||||
|
её размеру. При запуске он читает её и берёт 0,9 под общий предел собственной
|
||||||
|
памяти, а 0,5 — под размеры кэшей и под порог, после которого промежуточные
|
||||||
|
данные запроса уходят на диск. Поэтому «поднять предел ничего не стоит» верно
|
||||||
|
для девяти сервисов, которые своей коробки не читают, и неверно для двух нод: от
|
||||||
|
её размера зависит, когда сервер начинает себя ограничивать. Снять лимит с нод
|
||||||
|
по той же причине нельзя — без коробки каждая нода считает свои доли от всей
|
||||||
|
машины, и память кончится у машины раньше, чем сервер решит экономить. Панель
|
||||||
|
«не упёрлись ли ноды в память» из ADR 0002 без коробки тоже не работает:
|
||||||
|
упираться становится не во что.
|
||||||
|
|
||||||
|
Сумма всех пределов после правки больше восьми гигабайт, и это не противоречие.
|
||||||
|
`mem_limit` — верхняя граница, а не резерв: Docker ничего не откладывает
|
||||||
|
заранее, и в покое стенд занимает около 3,2 ГБ. Восемь гигабайт нужны не сумме
|
||||||
|
пределов, а работе с запасом.
|
||||||
|
|
||||||
|
Остальные девять лимитов не меняются, потому что ни один из них ни разу не
|
||||||
|
сработал. Снять их скопом — то же изменение без свидетельств, каким они были
|
||||||
|
выставлены, только в обратную сторону. Лечение здесь не в том, чтобы стереть
|
||||||
|
числа, а в том, чтобы лишить их статуса закона: число без основания меняют,
|
||||||
|
когда оно мешает, и не защищают как принятое решение.
|
||||||
|
|
||||||
|
ADR 0001 обосновывал отказ от triggerer, второго Postgres и внешних сборщиков
|
||||||
|
тем, что это удерживает стенд в пределе 3,4 ГБ. Предела больше нет, довод
|
||||||
|
отозван; сами решения в силе по своим основаниям — у triggerer это «в каркасе
|
||||||
|
нет отложенных задач», у общего Postgres — сэкономленный контейнер при
|
||||||
|
сохранённой границе владения данными. Часть про внешние сборщики уже
|
||||||
|
пересмотрена ADR 0002: сборщик метрик Kafka нужен ради отставания чтения.
|
||||||
|
Ближайшее следствие — этап 5: ожидание дневного батча заказов решается по
|
||||||
|
существу (сенсор в режиме poke, асинхронный оператор на воркере или отложенный
|
||||||
|
с triggerer), а не по остатку памяти.
|
||||||
|
|
||||||
|
## Что проверено
|
||||||
|
|
||||||
|
Замеры 1 августа 2026 года на закреплённых образах.
|
||||||
|
|
||||||
|
`clickhouse/clickhouse-server:26.3.17.56` в контейнере с `--memory 1g`:
|
||||||
|
`max_server_memory_usage` = 921,60 МиБ — посимвольно то же число, что в ошибке
|
||||||
|
инцидента; в журнале `Lowered mark cache size to 512.00 MiB because the system
|
||||||
|
has limited RAM`; `cache_size_to_ram_max_ratio` = 0,5; праздный сервер —
|
||||||
|
`VmRSS` 846 МиБ при `RssFile` 530 МиБ и `MemoryTracking` 113 МиБ.
|
||||||
|
|
||||||
|
Там же `max_bytes_ratio_before_external_group_by` и
|
||||||
|
`max_bytes_ratio_before_external_sort` = 0,5. Тяжёлый `GROUP BY` в коробке не
|
||||||
|
получает отказ, а уходит на диск и досчитывается; отказ по памяти остаётся для
|
||||||
|
того, что на диск не сбрасывается. Учебный сюжет «тяжёлый запрос — симптом на
|
||||||
|
графике памяти» из ADR 0002 выглядит ровной линией у верхней границы и
|
||||||
|
дисковой нагрузкой, а не обрывом.
|
||||||
|
|
||||||
|
cgroup v2: `docker stats` показывает `memory.current` минус неактивные файловые
|
||||||
|
страницы. На праздном контейнере — 1056 МБ при 779 МБ файловых и 234 МБ
|
||||||
|
анонимных.
|
||||||
|
|
||||||
|
`apache/kafka:4.3.1`: `kafka-server-start.sh` при пустой `KAFKA_HEAP_OPTS`
|
||||||
|
ставит `-Xmx1G -Xms1G`, а по размеру коробки кучу не подбирает. Поэтому
|
||||||
|
переменную не убираем: без неё куча стала бы больше, а не меньше, и в нынешней
|
||||||
|
коробке Kafka на гигабайт ядро убивало бы контейнер за нехватку памяти.
|
||||||
|
|
||||||
|
На стенде с новой коробкой в 4 ГиБ то же поведение подтвердилось:
|
||||||
|
`max_server_memory_usage` = 3,60 ГиБ, в журнале ноды `Lowered mark cache size
|
||||||
|
to 2.00 GiB because the system has limited RAM` и такие же строки про остальные
|
||||||
|
кэши. Сервер по-прежнему считает свои доли от коробки, просто коробка другая.
|
||||||
|
|
||||||
|
Семантика счётчиков Docker, на которой держится новая проверка, снята
|
||||||
|
отдельными контейнерами. Ручной `docker restart` оставляет `RestartCount` = 0 —
|
||||||
|
значит документированный в README перезапуск нод проверку не роняет. Убитый
|
||||||
|
ядром за память контейнер с политикой `unless-stopped` даёт `OOMKilled` = true
|
||||||
|
и растущий `RestartCount`: смерть видна и после того, как Docker поднял
|
||||||
|
контейнер заново. Убийство не за память `OOMKilled` не поднимает.
|
||||||
|
|
||||||
|
Значение `max_server_memory_usage_to_ram_ratio` = 0,9 и то, что в cgroup предел
|
||||||
|
считается от коробки, а не от машины, сверены по документации ClickHouse через
|
||||||
|
MCP Context7.
|
||||||
@@ -338,12 +338,21 @@ CSV в репозитории (`data/catalog/products.csv`: `sku`, `name`, `cate
|
|||||||
|
|
||||||
### Ресурсный бюджет (#10)
|
### Ресурсный бюджет (#10)
|
||||||
|
|
||||||
Расчёт на ноутбук менти с 16 ГБ памяти; у кого 8 ГБ — берёт VDS за свой счёт.
|
Предела расхода у стенда нет. Есть требование к машине: около 8 ГБ памяти,
|
||||||
Полный стенд в покое ≈3,4 ГБ. Топология 2×1 добавляет ≈0,6–0,8 ГБ — влезает
|
доступной Docker. Решение и его основания —
|
||||||
свободно. Топология 2×2 добавила бы ≈1,7–1,9 ГБ и упёрлась бы в дефолтный
|
[ADR 0004](../adr/0004-resource-limits.md); для менти то же самое объясняет
|
||||||
бюджет WSL2 (~8 ГБ) — это второй довод против реплик, рядом с главным
|
README.
|
||||||
(репликационная эксплуатация — отдельный операционный домен). Координатор —
|
|
||||||
clickhouse-keeper, а не ZooKeeper, в том числе из-за этого бюджета.
|
Прежняя оценка «полный стенд в покое ≈3,4 ГБ» была расчётом по
|
||||||
|
стенду-предшественнику, сделанным до первой сборки v2, и предела не задавала.
|
||||||
|
Проверка `make smoke`, сторожившая это число, убрана: она мерила потребление
|
||||||
|
вместе со страничным кэшем и с появлением настоящих данных начала бы краснеть
|
||||||
|
на здоровом стенде.
|
||||||
|
|
||||||
|
Топология 2×2 остаётся отвергнутой по главному доводу — репликационная
|
||||||
|
эксплуатация есть отдельный операционный домен. Второй довод, от бюджета, снят
|
||||||
|
вместе с бюджетом. Выбор clickhouse-keeper вместо ZooKeeper держится на
|
||||||
|
резолюции #14 и ссылки на бюджет больше не требует.
|
||||||
|
|
||||||
## 7. Слои: карта таблиц v2
|
## 7. Слои: карта таблиц v2
|
||||||
|
|
||||||
|
|||||||
+27
-28
@@ -590,41 +590,40 @@ check_superset() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
check_memory_budget() {
|
# Убитый за память контейнер Docker поднимает сам, и проверка здоровья об этом
|
||||||
local -a ids=()
|
# промолчит. Порога здесь нет: это «да или нет», а не бюджет памяти (ADR 0004).
|
||||||
|
check_containers_survived() {
|
||||||
local container_id
|
local container_id
|
||||||
local service
|
local service
|
||||||
local total_mib
|
local state
|
||||||
|
local problems=0
|
||||||
|
|
||||||
sleep 20
|
|
||||||
for service in "${LONG_LIVED_SERVICES[@]}"; do
|
for service in "${LONG_LIVED_SERVICES[@]}"; do
|
||||||
container_id="$(compose ps --status running --quiet "$service" 2>/dev/null || true)"
|
container_id="$(compose ps --all --quiet "$service" 2>/dev/null || true)"
|
||||||
if [[ -z "$container_id" || "$container_id" == *$'\n'* ]]; then
|
if [[ -z "$container_id" || "$container_id" == *$'\n'* ]]; then
|
||||||
fail "не удалось получить работающий контейнер ${service} для измерения памяти"
|
fail "не удалось получить контейнер ${service} для проверки перезапусков"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
ids+=("$container_id")
|
state="$(docker inspect --format '{{.State.OOMKilled}}/{{.RestartCount}}' "$container_id" 2>/dev/null || true)"
|
||||||
|
case "$state" in
|
||||||
|
false/0) ;;
|
||||||
|
# OOMKilled встаёт и когда убит процесс внутри живого контейнера.
|
||||||
|
true/*)
|
||||||
|
fail "в контейнере ${service} ядро убило процесс из-за нехватки памяти"
|
||||||
|
problems=$((problems + 1))
|
||||||
|
;;
|
||||||
|
false/*)
|
||||||
|
fail "контейнер ${service} перезапускался, счётчик Docker — ${state#*/}"
|
||||||
|
problems=$((problems + 1))
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
fail "Docker не рассказал о состоянии контейнера ${service}"
|
||||||
|
problems=$((problems + 1))
|
||||||
|
;;
|
||||||
|
esac
|
||||||
done
|
done
|
||||||
if ! total_mib="$(docker stats --no-stream --format '{{.MemUsage}}' "${ids[@]}" 2>/dev/null | awk -v expected="${#ids[@]}" '
|
if [[ "$problems" -eq 0 ]]; then
|
||||||
$1 ~ /GiB$/ {sub(/GiB$/, "", $1); total += $1 * 1024; next}
|
pass 'ни в одном долгоживущем контейнере ядро не убивало процессы за память, и никто не перезапускался сам'
|
||||||
$1 ~ /MiB$/ {sub(/MiB$/, "", $1); total += $1; next}
|
|
||||||
$1 ~ /KiB$/ {sub(/KiB$/, "", $1); total += $1 / 1024; next}
|
|
||||||
$1 ~ /GB$/ {sub(/GB$/, "", $1); total += $1 * 1000 / 1.048576; next}
|
|
||||||
$1 ~ /MB$/ {sub(/MB$/, "", $1); total += $1 / 1.048576; next}
|
|
||||||
$1 ~ /kB$/ {sub(/kB$/, "", $1); total += $1 / 1048.576; next}
|
|
||||||
{invalid = 1}
|
|
||||||
END {
|
|
||||||
if (invalid || NR != expected) exit 1
|
|
||||||
printf "%.1f", total
|
|
||||||
}
|
|
||||||
')"; then
|
|
||||||
fail 'Docker не вернул полное измерение памяти стенда'
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
if awk -v total="$total_mib" 'BEGIN {exit !(total <= 3242.5)}'; then
|
|
||||||
pass "стенд занимает ${total_mib} MiB после 20 секунд покоя, порог 3,4 ГБ не превышен"
|
|
||||||
else
|
|
||||||
fail "стенд занимает ${total_mib:-неизвестно} MiB после 20 секунд покоя, это больше 3,4 ГБ"
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,7 +637,7 @@ if check_host_dependencies; then
|
|||||||
check_grafana_datasource
|
check_grafana_datasource
|
||||||
check_airflow
|
check_airflow
|
||||||
check_superset
|
check_superset
|
||||||
check_memory_budget
|
check_containers_survived
|
||||||
else
|
else
|
||||||
fail 'проверки контейнеров, Kafka, Airflow, Superset, Prometheus и Grafana пропущены без зависимостей машины'
|
fail 'проверки контейнеров, Kafka, Airflow, Superset, Prometheus и Grafana пропущены без зависимостей машины'
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ set -euo pipefail
|
|||||||
|
|
||||||
readonly ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
readonly ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
readonly README="$ROOT_DIR/README.md"
|
readonly README="$ROOT_DIR/README.md"
|
||||||
readonly SMOKE="$ROOT_DIR/scripts/stand-smoke.sh"
|
|
||||||
passed=0
|
passed=0
|
||||||
|
|
||||||
fail() {
|
fail() {
|
||||||
@@ -93,25 +92,10 @@ restart_lesson_present() {
|
|||||||
' "$README"
|
' "$README"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Единица памяти в отчёте проверки — русская «ГБ», а не латинская «GB»
|
|
||||||
# (контракт языка из AGENTS.md). Здесь успех — это отсутствие образца, поэтому
|
|
||||||
# код возврата grep разбирается вручную: 1 — не нашли, и это хорошо; 0 — нашли
|
|
||||||
# латинское; больше 1 — сам grep не отработал, и молчать об этом нельзя.
|
|
||||||
smoke_uses_russian_unit() {
|
|
||||||
local status=0
|
|
||||||
grep -q '3,4 GB' "$SMOKE" || status=$?
|
|
||||||
case "$status" in
|
|
||||||
1) return 0 ;;
|
|
||||||
0) return 1 ;;
|
|
||||||
*) fail "не удалось проверить обозначение единицы памяти в $SMOKE" ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
check 'README перечисляет HTTP- и нативные порты обеих нод' ports_documented
|
check 'README перечисляет HTTP- и нативные порты обеих нод' ports_documented
|
||||||
check 'README объясняет сброс томов после смены исходных учётных данных' clean_advice_present
|
check 'README объясняет сброс томов после смены исходных учётных данных' clean_advice_present
|
||||||
check 'список портов остаётся единым списком' ports_stay_one_list
|
check 'список портов остаётся единым списком' ports_stay_one_list
|
||||||
check 'README перечисляет малые проверки пробников в составе config-test' probe_checks_documented
|
check 'README перечисляет малые проверки пробников в составе config-test' probe_checks_documented
|
||||||
check 'README требует перезапуск ClickHouse после изменения настройки метрик' restart_lesson_present
|
check 'README требует перезапуск ClickHouse после изменения настройки метрик' restart_lesson_present
|
||||||
check 'отчёт проверки использует русское обозначение ГБ' smoke_uses_russian_unit
|
|
||||||
|
|
||||||
printf 'ИТОГ: пройдено %d, ошибок 0\n' "$passed"
|
printf 'ИТОГ: пройдено %d, ошибок 0\n' "$passed"
|
||||||
|
|||||||
Reference in New Issue
Block a user