Глава 1: Основы Linux для анализа производительности
Прежде чем погружаться в код melisai, нужно понять, откуда берутся данные о производительности. Linux не имеет «API производительности» — вместо этого ядро предоставляет данные через виртуальные файловые системы.
Файловая система /proc (procfs)
/proc — виртуальная файловая система. Она не живёт на диске. Каждый раз, когда вы читаете файл в /proc, ядро генерирует содержимое «на лету» из внутренних структур данных. Никакого дискового I/O не происходит.
Ключевые файлы, используемые melisai
| Файл | Содержимое | Кем используется |
|---|---|---|
/proc/stat |
Счётчики CPU по ядрам | CPUCollector |
/proc/loadavg |
Средняя нагрузка 1/5/15 мин | CPUCollector |
/proc/meminfo |
Детализация памяти | MemoryCollector |
/proc/vmstat |
Счётчики VM (page faults, paging) | MemoryCollector |
/proc/buddyinfo |
Фрагментация памяти по зонам | MemoryCollector |
/proc/pressure/memory |
PSI (инфо о стагнации давления) | MemoryCollector |
/proc/diskstats |
Счётчики I/O по устройствам | DiskCollector |
/proc/net/dev |
Трафик по интерфейсам | NetworkCollector |
/proc/net/snmp |
Статистика TCP/UDP/IP | NetworkCollector |
/proc/[pid]/stat |
CPU-время и состояние процесса | ProcessCollector |
/proc/[pid]/fd/ |
Число открытых дескрипторов | ProcessCollector |
/proc/1/cgroup |
Членство в cgroup | ContainerCollector |
Дельта-сэмплирование
Все счётчики /proc монотонно возрастают. Чтобы получить текущую скорость, нужны два чтения с интервалом:
Чтение 1 при T=0: cpu user=10000 system=5000 idle=85000
Чтение 2 при T=1с: cpu user=10100 system=5020 idle=85880
Дельта: user=100 system=20 idle=880
Всего: 100 + 20 + 880 = 1000 тиков
user% = 100 / 1000 × 100 = 10.0%
system% = 20 / 1000 × 100 = 2.0%
idle% = 880 / 1000 × 100 = 88.0%
Файловая система /sys (sysfs)
/sys представляет модель устройств ядра. В отличие от /proc, /sys — это дерево, отражающее иерархию оборудования/драйверов.
Ключевые пути
/sys/block/sda/queue/scheduler ← Активный планировщик I/O
/sys/block/sda/queue/rotational ← 1=HDD, 0=SSD
/sys/fs/cgroup/ ← Иерархия control group
/sys/devices/system/node/ ← NUMA-топология
Тики (Jiffies) и учёт времени
Linux измеряет CPU-время в тиках — дискретных единицах. Частота определяется параметром ядра HZ:
| HZ | 1 тик | Где встречается |
|---|---|---|
| 100 | 10 мс | Большинство серверов |
| 250 | 4 мс | Обычные десктопы |
| 1000 | 1 мс | Ядра с низкой задержкой |
Состояния CPU
Каждый тик каждое ядро CPU находится ровно в одном состоянии:
| Состояние | Описание |
|---|---|
| user | Выполнение пользовательского кода |
| nice | Пользовательский код с пониженным приоритетом |
| system | Код ядра (системные вызовы, драйверы) |
| idle | Простой, ожидание работы |
| iowait | Простой но с ожиданием завершения I/O |
| irq | Обработка аппаратных прерываний |
| softirq | Обработка программных прерываний |
| steal | Время, украденное гипервизором (только VM) |
Частое заблуждение об iowait: IOWait НЕ означает «CPU занят I/O». Он означает «CPU простаивает И имеет ожидающий I/O». Если у системы есть другие задачи, эти тики покажутся как user/system, даже с таким же объёмом I/O.
Control Groups (cgroups)
| Версия | Иерархия | Интерфейс |
|---|---|---|
| v1 | Несколько деревьев | cpu.cfs_quota_us, memory.limit_in_bytes |
| v2 | Единое дерево | cpu.max, memory.max |
PSI (Pressure Stall Information)
| Значение | Смысл |
|---|---|
| some=0% | Нет давления |
| some=25% | Значительная конкуренция за память |
| full=5% | ВСЕ задачи заблокированы 5% времени — критично |
NUMA
На серверах с несколькими сокетами — каждый CPU имеет «локальную» память (быстро) и «удалённую» память (через интерконнект, в 2-3× медленнее). melisai отслеживает numa_hit vs numa_miss.
Далее: Глава 2 — Анализ CPU