> Что означает строка load average в Linux (Go)
Уровень: senior · Роль: backend · Категория: Технические вопросы
Компании: VK
Стек: Go
> Пример ответа
Короткий ответ
load average в Linux - это среднее количество процессов в состоянии running или uninterruptible sleep за 1, 5 и 15 минут. Это не процент загрузки CPU, а число потоков, ожидающих выполнения или ожидающих ввода-вывода. Для интерпретации важно сравнивать значение с количеством ядер: load average 4.0 на 4-ядерной машине означает полную загрузку, а на 8-ядерной - 50%.
Подробное объяснение
Ядро Linux вычисляет load average как экспоненциально взвешенное скользящее среднее (EWMA) от количества задач в двух состояниях:
- TASK_RUNNING - процесс выполняется или готов к выполнению и стоит в очереди на CPU.
- TASK_UNINTERRUPTIBLE - процесс заблокирован в системном вызове (обычно ожидание дискового I/O, NFS, блокировок ядра) и не может быть прерван сигналом.
Значения выводятся в трёх окнах: 1, 5 и 15 минут. Формула обновления: load = load * exp(-1/window) + n * (1 - exp(-1/window)), где n - текущее число активных задач.
Ключевые нюансы:
- Многоядерность: load average не нормируется на число ядер. На 8-ядерной системе значение 8.0 - это 100% утилизация всех ядер, но на 4-ядерной - уже перегрузка в 2 раза.
- Uninterruptible sleep: процессы, ждущие I/O, тоже учитываются. Поэтому высокий load average при низком CPU usage часто указывает на проблемы с диском или сетью.
- Не путать с CPU usage:
topпоказывает %CPU как долю времени, а load average - это длина очереди. Один процесс может давать 100% CPU, но load average будет 1.0. - Пики vs тренд: значение за 1 минуту отражает краткосрочные всплески, за 15 минут - устойчивый тренд. Резкий рост 1-минутного значения при стабильном 15-минутном - это временная нагрузка.
На практике
Для backend-разработчика на Go важно понимать, как load average соотносится с поведением приложения:
- GOMAXPROCS по умолчанию равен числу ядер, но если load average высокий из-за других процессов, горутины будут ждать планировщика дольше.
- Блокирующие операции (file I/O, network calls) в Go не создают TASK_UNINTERRUPTIBLE - они переключаются на другие горутины, поэтому load average может оставаться низким даже при высокой задержке.
- Мониторинг: для сервисов с интенсивным I/O (базы данных, прокси) load average часто более показателен, чем CPU usage. Например, PostgreSQL при активной работе с диском может показывать load average 10 при 20% CPU.
Практические рекомендации:
- Сравнивайте load average с
nproc(число ядер), а не с абсолютными значениями. - Смотрите
vmstatилиiostatдля различения CPU-bound и I/O-bound нагрузки. - Для Go-сервисов используйте
runtime.NumGoroutine()и метрики задержек - они точнее отражают состояние приложения, чем load average.
Пример кода
GO// Пример: получение load average из /proc/loadavg в Gopackage mainimport ("fmt""os""strconv""strings")func getLoadAverage() (float64, float64, float64, error) {data, err := os.ReadFile("/proc/loadavg")if err != nil {return 0, 0, 0, err}fields := strings.Fields(string(data))if len(fields) < 3 {return 0, 0, 0, fmt.Errorf("unexpected format")}load1, err1 := strconv.ParseFloat(fields[0], 64)load5, err2 := strconv.ParseFloat(fields[1], 64)load15, err3 := strconv.ParseFloat(fields[2], 64)if err1 != nil || err2 != nil || err3 != nil {return 0, 0, 0, fmt.Errorf("parse error")}return load1, load5, load15, nil}func main() {load1, load5, load15, err := getLoadAverage()if err != nil {fmt.Println("Error:", err)return}fmt.Printf("load average: %.2f, %.2f, %.2f\n", load1, load5, load15)}
Как отвечать на собеседовании
Начните с точного определения: "это среднее число процессов в состоянии running или uninterruptible sleep". Затем добавьте про три окна времени и экспоненциальное сглаживание. Обязательно упомяните, что значение не нормируется на число ядер - это частая ошибка. Приведите пример: "на 4-ядерной машине load average 4.0 - это полная загрузка, а 8.0 - перегрузка в 2 раза".
Если спросят про Go - свяжите с планировщиком горутин: "Go-приложение может иметь низкий load average, но высокую задержку из-за блокировок на уровне ОС". Покажите понимание разницы между CPU-bound и I/O-bound нагрузкой.
Что проверяет интервьюер
- Понимание разницы между load average и CPU usage.
- Знание, что учитываются процессы в uninterruptible sleep.
- Умение интерпретировать значения в контексте количества ядер.
- Понимание экспоненциального сглаживания и окон времени.
- Способность связать метрику с реальными проблемами (диск, сеть, планировщик).
Типичные ошибки
- Утверждение, что load average - это процент загрузки CPU.
- Игнорирование числа ядер при интерпретации.
- Незнание про TASK_UNINTERRUPTIBLE - кандидат не может объяснить высокий load при низком CPU.
- Путаница между load average и очередью run queue в
vmstat(это разные метрики, хотя и связанные). - Утверждение, что load average всегда должен быть меньше числа ядер - на самом деле значения выше числа ядер допустимы для краткосрочных пиков.
> Похожие задачи по backend
Как определить значение при коллизии в цепочке хэш-таблицы
Что такое аннотация в Go и зачем она нужна
Как пользоваться программой top в Linux
Какие виды уведомлений используются в системах (SMS, push, email и т.д.)
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью