Производительность — один из наиболее заметных параметров системы. Именно на её недостаток чаще всего жалуются пользователи. Ниже приведены некоторые элементарные способы по анализу производительности системы.
Часто ошибочно считает, что поднять скорость системы можно хорошо «оптимизировав» конфиги. Это редко бывает так. Оригинальные стоковые конфиги репозиторного софта подходят для решения многих задач. Их можно (и нужно) менять для достижения задач конкретного проекта. Естественно, все изменения следует сопровождать тестами производительности, а для этого должны быть соответствующие методики и инструменты.
Прежде чем что-то пытаться менять в конфигурации необходимо найти проблемные (узкие) места в системе. В общем случае методика исследования следующая:
- Собирайте и анализируйте статистические данные о работе системы. На минимальном уровне это решается различными системами мониторинга, например,
munin
,Zabbix
. В более продвинутом случае — свои плагины к этим системам мониторинга или собственные скрипты. Если пару дней назад всё работало отлично, а сейчас какие-то «тормоза» — мониторинг поможет установить их источник. Кроме этого, мониторинг позволяет обнаружить еще не проявившиеся проблемы, когда используемые ресурсы системы исчерпываются. - Журналируйте собственные изменения конфигурации. И сравнивайте динамику производительности (по собранным статистическим данным) до включения новой конфигурации и после нее. Это поможет узнать, какие изменения действительно эффективны, а какие бесполезны или даже вредны. Также, журналирование позволит оперативно обнаружить медленный код в бизнес-приложениях.
- Не перегружайте систему. На небольших нагрузках кажется, что ресурсов системы очень и очень достаточно впрок. Однако, это не так. Когда загрузка какого-либо из ключевых параметов системы подходит к 100% (это может быть, например, загрузка ЦП, или ввода-вывода или даже наличие свободного места на дисках), «тормоза» системы возрастают нелинейно. В том числе это происходит из-за «накладных расходов», т.е. ресурсов системы не расходуемых на определённые процессы, а теряемые в процессе работы ОС и переключения задач.
Процессорное время (CPU)
Load average легко собираются любым мониторингом круглосуточно и его необходимо анализировать. Максимальное значение LA (в часы наибольшей нагрузки) не должно превосходить возможностей системы, т.е. количества её ядер CPU. В противном случае неизбежно замедление работы приложений, причем с увеличением LA выше возможностей системы будут возрастать потери на переключении контекста.
Когда LA достаточно высок имеет смысл посмотреть на что именно расходуются ресурсы процессора. Простейший способ это сделать — посмотреть процессы с наибольшим процессорным временем (TIME) в выводе утилит top
, htop
или ps aux
. Далее уже пытаться снизить нагрузку именно на этом звене.
Часто считается, что процессорная мощность это основной показатель, влияющий на общую производительность системы. Это действительно так лишь в некоторых узких применениях, например в численных расчетах. Во многих других прикладных задачах это не так.
В тех же top
и htop
следует обратить внимание на процессы в состоянии D
, которое обычно соответствует ожиданию ввода-вывода процесса, а также на заполнение свопа. Но об этом ниже.
Коротко (для скриптов мониторинга) значение LA можно взять из параметров системы:
cat /proc/loadavg
Вручную — легче в top
и htop
.
Характеристики использования процессорного времени отображается также командой vmstat
:
$ vmstat procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 0 0 7596 329216 13260 14506756 0 0 4625 26 42 145 4 1 81 13 0
vmstat
принимает 2 аргумента: время в секундах, в течение которого необходимо наблюдать за системой, и количество генерируемых отчетов. Эту утилиту полезно запускать для наблюдения, например для формирования 10 отчетов по 1 минуте каждый:
vmstat 60 10
Колонки us (user)
и sy (system)
означают соответсвенно процессорное время затраченное на пользовательские процессы (демоны и прикладного ПО) и системное. Для большинства систем нормально, если время распределяется между ними поровну.
in (interrupts)
и cs (context switches)
это количества прерываний и переключений контекста, и оба эти параметра — накладные расходы системы и их не должно быть много.
Разбивку использования CPU по ядрам можно получить с помощью mpstat
, например по всем ядрам
$ mpstat -P ALL Linux 3.2.0-4-amd64 (sys01) 01/05/15 _x86_64_ (16 CPU) 16:09:51 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle 16:09:51 all 3.55 18.39 9.83 1.24 0.00 0.50 0.00 0.00 66.49 16:09:51 0 5.85 43.47 11.04 1.62 0.00 6.79 0.00 0.00 31.23 16:09:51 1 4.23 29.35 10.81 1.34 0.00 0.11 0.00 0.00 54.17 16:09:51 2 3.86 24.70 10.17 1.26 0.00 0.11 0.00 0.00 59.90 16:09:51 3 3.66 22.73 9.64 1.10 0.00 0.13 0.00 0.00 62.74 16:09:51 4 6.01 15.49 8.84 4.94 0.00 0.26 0.00 0.00 64.47 16:09:51 5 3.15 12.93 8.29 1.43 0.00 0.08 0.00 0.00 74.13 16:09:51 6 2.93 12.90 8.11 1.08 0.00 0.08 0.00 0.00 74.90 16:09:51 7 2.79 14.15 8.43 0.87 0.00 0.07 0.00 0.00 73.69 16:09:51 8 4.01 24.11 8.93 0.93 0.00 0.04 0.00 0.00 61.98 16:09:51 9 2.89 15.37 10.24 0.84 0.00 0.07 0.00 0.00 70.60 16:09:51 10 2.91 15.56 10.64 0.85 0.00 0.07 0.00 0.00 69.98 16:09:51 11 2.78 15.35 10.61 0.81 0.00 0.09 0.00 0.00 70.36 16:09:51 12 2.89 11.69 8.56 0.84 0.00 0.04 0.00 0.00 75.98 16:09:51 13 3.58 12.81 12.09 0.66 0.00 0.03 0.00 0.00 70.83 16:09:51 14 2.95 12.32 11.24 0.66 0.00 0.03 0.00 0.00 72.80 16:09:51 15 2.36 11.60 9.59 0.59 0.00 0.04 0.00 0.00 75.82
Выводимые параметры утилиты понимающему человеку там очевидны.
Оперативная память (RAM)
Использование оперативной памяти «на ходу» анализируется с помощью утилит htop
, vmstat
, free
. Лучше — смотреть в динамике в мониторинге, том же мунине. Прежде всего необходимо обратить внимание на использование свопа, который в хорошей должен быть почти свободным и не увеличиваться/уменьшаться в определённое время суток.
В выводе
$ free -h total used free shared buffers cached Mem: 47G 44G 2.3G 0B 559M 26G -/+ buffers/cache: 18G 29G Swap: 15G 3.6G 12G
если окажется мало free-памяти, но много cached — это нормально. Память может быть занята страничным кэшем (cached), который многократно увеличивает скорость дисковых операций. Когда «свободной» (free) памяти действительно много это даже плохо и означает, что она не полностью используется. То же самое относится к выводу vmstat
.
Ввод-вывод (IO, input-output)
Статистику по ввода-выводу системы лучше собирать пакетами мониторинга. Параметр системы, на который в первую очередь необходимо обратить внимание — iowait
, т.е. ожидание ввода-вывода. Его подробные значения можно получить, например, с помощью mpstat
:
mpstat -P ALL
Сводные значения есть также в top
, vmstat
.
Часто признаком наличия проблем с вводом-выводом является большое количество процессов в состоянии D (uninterruptible sleep), в которое процесс переходит при ожидании ввода-вывода. Это не обязательно означает, что дело именно в I/O, но такая ситуация в любом случае должна быть исследована.
Счетчики чтения-записи с дисковых устройств получаются по
$ vmstat -d disk- ------------reads------------ ------------writes----------- -----IO------ total merged sectors ms total merged sectors ms cur sec sda 90878564 7454833 2829423640 647949492 205895042 265140200 14858972810 2510368504 0 448274 sdb 455801809 14612605 57375867578 2021813576 434699644 365377967 109699014136 4291627964 0 2081456 sdd 94938371 343221533 57971885640 3782143884 34980046 34425685 8816083324 1994769084 0 449787 sdf 83996804 354254620 57971510608 1338153836 35203200 34649634 8822861163 2201253492 0 462982 sde 83274303 354838922 57968955195 1266856936 34793484 34477071 8818425628 2217294360 0 461751 sdc 112569402 325806501 57972989224 4284077532 35217039 34782607 8820518859 2068813212 0 446935 sr0 0 0 0 0 0 0 0 0 0 0 loop0 0 0 0 0 0 0 0 0 0 0 loop1 0 0 0 0 0 0 0 0 0 0 loop2 0 0 0 0 0 0 0 0 0 0 loop3 0 0 0 0 0 0 0 0 0 0 loop4 0 0 0 0 0 0 0 0 0 0 loop5 0 0 0 0 0 0 0 0 0 0 loop6 0 0 0 0 0 0 0 0 0 0 loop7 0 0 0 0 0 0 0 0 0 0 md0 289404098 0 44556083939 0 123718867 0 17627362527 0 0 0
Еще более удобная утилита для этого — iostat
. Как и vmstat
, она принимает 2 параметра (время наблюдения и количество отчетов). Полезно снять несколько расширенных отчетов за некоторый промежуток времени, например, минуту:
$ iostat -x 60 5 avg-cpu: %user %nice %system %iowait %steal %idle 7.83 47.27 21.99 1.52 0.00 21.39 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0.50 42.87 7.70 40.28 37.27 1732.40 73.76 5.40 112.63 13.26 131.62 2.05 9.83 sdb 9.52 56.27 85.38 60.47 1459.00 5955.80 101.68 14.10 96.69 13.17 214.63 2.46 35.85 sdd 0.08 0.27 0.08 1.47 11.27 40.27 66.49 0.01 5.59 24.80 4.50 4.90 0.76 sdf 0.22 0.50 0.15 2.35 30.27 53.75 67.21 0.02 6.43 31.11 4.85 4.83 1.21 sde 0.17 0.45 0.15 2.28 24.47 44.45 56.64 0.01 4.77 11.11 4.35 3.12 0.76 sdc 0.17 0.32 0.73 1.53 25.47 49.57 66.21 0.02 8.44 12.91 6.30 4.68 1.06 md0 0.00 0.00 1.75 3.25 91.47 93.52 73.99 0.00 0.00 0.00 0.00 0.00 0.00
и по результатам сделать выводы, на какие устройства идет запись или чтение, и как перераспределить содержимое файловой системы для более эффективного использования. Там же есть статистика по iowait
.
Сеть (Network)
В первую очередь при определении характеристик сетевых интерфейсов необходимо посмотреть количество ошибок на них, что элементарно делается древней командой ifconfig
. Если интерфейс показывает существенное количество ошибок, следует удостовериться в корректности работы сетевой карты и физической сети до маршрутизатора.
Обязательно необходимо убедиться, что настройки скорости и дуплексного режима верны для сетевой карты. Это можно сделать (и изменить) с помощью утилит ethtool
и mii-tool
:
ethtool eth0
Обычно сетевые карты автоматически узнают сеть, её скорость и дуплексность, но это не всегда так. Иногда встречаются системы, работающие медленно лишь потому, что сетевая карта работает в полудуплексном режиме, что очень сильно снижает производительность и задержку даже ненагруженных систем. В случае полудуплекса или низкой автоопределённой скорости интерфейса, её имеет смысл повысить
ethtool -s eth0 autoneg off speed 100 duplex full
Полезно посмотреть и другие параметры интерфейсов, грепнув их вывода ядра:
dmesg | grep -i eth
Пиковую загрузку сети лучше (как и многое остальное) мониторить постоянно и автоматически, например, тем же munin
. Ориентироваться лучше на пиковую нагрузку — по ней должен быть определённый запас и в её время не должно быть больших значений iowait.
Хорошую статистику по сети и разбивку по типам траффика можно получать с помощью ntop
.
Что делать
Многие убеждены, что производительность можно многократно поднять («оптимизировать») чисто софтовыми способами, т.е. изменением настроек операционной системы и прикладного софта. На деле это не всегда так.
Ядра современных дистрибутивов Linux уже хорошо настроены в плане производительности. Если задача типовая и «железо» устраивает — менять ничего не нужно. Изменение каких-либо параметров через sysctl на большинстве серверных задач не повысит скорость работы, а при плохом подгоне даже понизит. Тем более, следует скептически относиться ко всем интернет-советам по оптимизации (в том числе, описанным на этом сайте).
Какие-то параметры работы можно оптимизировать: настройками прикладного софта, перераспределением файловой системы. Но большинстве случаев наилучший способ повысить производительности системы — «железный», т.е. изменением аппаратных характеристик сервера или распределением и балансировкой нагрузки по разным серверам. При высокой нагрузке на I/O поможет использование RAID, программных (mdadm) или аппаратных.
На масштабирование «железа» и стоит в перспективе ориентироваться и не строить иллюзий по поводу софтовых оптимизаций.