Когда тормозит highload‑система: чеклист глазами SRE k8s
Сервер тормозит, пользователи жалуются, а CPU в норме. Знакомо? В highload‑среде (Kafka, Patroni, RabbitMQ) это почти всегда «узкое место» на стыке Linux и приложения: диск, сеть или память. Как SRE с опытом в k8s, Ansible, Kafka и Postgres (Patroni+PgBouncer), я не гадаю — я иду по чек‑листу и сразу соотношу метрики с состоянием сервисов. Ниже — мой рабочий алгоритм.
Шаг 1. Общая картина: нагрузка и аптайм uptime w Смотрю load average (LA) и соотношу с числом ядер. В highload важно помнить: LA учитывает процессы в ожидании I/O. Поэтому LA может быть высоким даже при низком CPU — и это как раз наш случай в Kafka или Postgres. В w проверяю активные сессии: иногда «тормоза» вызывает зависший запрос к базе или долгая сборка в Jenkins.
Шаг 2. Процессы и потребление ресурсов (в т. ч. в k8s) top # или удобнее: htop Сортирую по CPU (P) или по памяти (M в top). Обращаю внимание на статус: процессы в состоянии D(uninterruptible sleep) часто ждут I/O и могут блокировать другие задачи — критично для Kafka и Postgres. Если используется k8s, параллельно смотрю: kubectl top pods --all-namespaces kubectl describe pod <pod-name> Это помогает понять, не упирается ли под в лимиты (limits) или не падает ли он из‑за OOM.
Шаг 3. Память и своп free -h Ориентируюсь на available, а не на free: Linux активно использует память под кэш — это нормально. Но активный своп — тревожный сигнал: для Kafka и Redis это почти гарантированные тормоза. Для Patroni/Postgres: высокий кэш может быть полезен, но если начинается своп — производительность падает резко. В таких случаях проверяю настройки vm.min_free_kbytes и лимиты в k8s.
Шаг 4. Системные ожидания и I/O (критично для Kafka, Postgres, RabbitMQ) vmstat 2 10 iostat -x 2 5 В vmstat смотрю колонку wa (wait) — процент времени, когда CPU ждёт I/O. Высокие значения = узкое место в I/O — частая причина тормозов Kafka и Postgres. В iostat смотрю %util — насколько загружен диск. Если близко к 100%, диск не успевает обрабатывать запросы. Также полезны r/s, w/s, avgqu-sz, await. Для детальной диагностики по процессам использую iotop. В k8s: если диск тормозит, проверяю PVC и StorageClass: kubectl get pvc kubectl describe pvc <pvc-name> Иногда проблема не в Linux, а в медленном Storage или сетевой задержке до хранилища.
Шаг 5. Дисковое пространство и файловые системы (важно для логов и WAL) df -h df -i du -sh /path Проверяю заполненность разделов, особенно /, /var, /data. Для Postgres (Patroni) критичны места под WAL и данные. Даже если место есть, можно исчерпать иноды — это тоже вызывает проблемы. Для наглядного анализа места удобно использовать ncdu.
Шаг 6. Ядро и аппаратные ошибки (включая OOM и сетевые проблемы) dmesg | tail -n 50 journalctl -p err -n 100 Ищу сообщения об ошибках дисков, RAID, сетевых карт, OOM‑killer. Если вижу срабатывания OOM‑killer — проблема в потреблении памяти. При подозрении на диск проверяю SMART: smartctl -a /dev/sdX. Для HAProxy и NGFW: проверяю также логи и метрики балансировщика и фаервола — иногда «тормоза» вызваны таймаутами или блокировками на сетевом уровне.
Реальный пример из практики (k8s + Kafka + Patroni) На одном из highload‑кластеров пользователи жаловались на задержки. Load average был 12 на 8‑ядерной машине, CPU — в районе 30–40%. В vmstat увидел высокий wa — система много времени ждала I/O. В iostat — %util на основном диске был 100%. В iotop нашёл скрипт бэкапа, который активно писал на тот же диск, где крутились базы данных и топики Kafka. Перенёс бэкапы на отдельный том и настроил отдельный StorageClass в k8s — load average упал до 2, задержки в Kafka и Postgres снизились в 3–5 раз, пользователи перестали жаловаться. Параллельно обновил лимиты и requests в Helm‑чартах для Postgres и Kafka, чтобы избежать повторных проблем.
А у вас бывали случаи, когда тормоза были не из‑за CPU, а из‑за I/O или сетевых задержек? Расскажите в комментариях — интересно собрать коллекцию типовых сценариев.