> Что означает строка 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 в Go
package main
import (
"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 всегда должен быть меньше числа ядер - на самом деле значения выше числа ядер допустимы для краткосрочных пиков.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью