vmstat, sar и первичная диагностика производительности

Unix-системы имеют несколько замечательных встроенных утилит для диагностики проблем производительности. Можно удивиться, узнав, сколь многое говорит о системе буквально дюжина параметров, выдаваемая встроенной командой vmstat!

К сожалению, особенно при самостоятельном изучении Linux, понимание vmstat часто относится к области высоких академических знаний и не заслуженно игнорируется. Ситуация усугубляется еще и тем, что ряд заметок и тредов на данную тему содержат предположения, довольно далекие от реальности.

Попробуем исправить это недоразумение ;)

skycover:~# (sleep 3; dd if=/dev/xvda1 of=/dev/null)& vmstat 1
[1] 31169
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 1  0 115676  17096   4724  48888    0    1     2    12   11   30  0  0 97  2
 0  0 115676  16584   4724  48892    0    0     0     0   50   73  1  1 98  0
 0  0 115676  16336   4724  48896    0    0     0     0   28   60  0  0 100  0
 0  0 115676  16336   4724  48896    0    0     0     0   21   32  0  0 100  0
 1  2 116076   4992  40544  25796   32  404 84556  1140 3521 1518  7 34  0 58
 0  3 116076   4876  39732  26468    0    0 63204     0 2339 1346  5 18  0 76
 1  1 116076   4876  39756  25832    0    0 59272     0 2069 1482  4 18  0 78
 1  1 116076   4892  39756  25812    0    0 95360     0 3741 1913 11 36  0 51

Это типичный вывод команды vmstat, с по-секундной выборкой и имитацией дисковой нагрузки, которая начинается с небольшой задержкой.

Виртуальная память

Для начала стоит пробежаться по концепции виртуальной памяти Linux.

Paging

В Linux загрузка программных модулей в оперативную память, а также выполнение дисковых операций через memory-mapped файлы осуществляется посредством отображения дисковых файлов на регионы виртуальной оперативной памяти. При этом физического чтения/записи данных, равно как и выделения под них места в физической оперативной памяти, не происходит до момента обращения к ним.

Когда ядро или программа обращается к не существующей странице отображенной памяти, контроллер памяти генерирует прерывание Major Page Fault (MPF). В ответ, ядро выделяет физическую страницу памяти для размещения данных и загружает в нее блок с жествого диска. Страница памяти, выделенная для хранения этого блока данных, помечаетcя как «cached» и даже после использования остается в оперативной памяти.

При повторном обращении к этому блоку (даже из другого процесса) возникнет Minor Page Fault (MnPF) и данные запросившему процессу будут предоставлены из cached-страницы, без непосредственного обращения к диску.

При записи на диск, данные помещаются в cached-страницу, страница помечается как «грязная» (dirty), и вскоре планировщик ввода-вывода (pdflush) синхронизирует ее на диск.

Чем больше обращений к диску, тем больше растет cached-память, многократно увеличивая эффективность дисковых операций. Одновременно уменьшается свободная оперативная память (free). Поэтому в типичной нагруженной системе количество неиспользуемой «свободной» памяти обычно очень не велико и это свидетельствует об эффективности работы виртуальной памяти.

Cached-память считается свободной и суммируется с free при вычислении реального количества свободной оперативной памяти в системе.

Что происходит, когда системе требуется оперативная память? Cached-страницы, не помеченные «грязными», просто удаляются – ведь их всегда можно обратно прочитать с диска!

Этот процесс называется paging и его измеряют в количестве страниц, загружаемых в память (page-in) и выгружаемых из памяти (page-out).

Swap и swapping

В старых *nix системах процесс swapping’а был связан с выгрузкой всей памяти какого-либо процесса на диск. В Linux все гораздо менее драмматично.

Любой процесс, помимо данных, отображаемых на диск имеет «анонимную» оперативную память – ту, в которой динамически размещаются структуры данных и происходят вычисления. При необходимости освобождения оперативной памяти, анонимные страницы памяти отображаются на дисковые блоки, расположенные на swap-разделе, выгружаются в них и затем освобождают оперативную память, в точности как при paging-е обычных дисковых данных.

Собственно, swapping и является частью процесса paging-a, однако, если при отображении реальных файлов, освобождение cached-памяти происходит безболезненно, swapping порождает page-out операцию (swap-out), связаную с выгрузкой части used-памяти на диск (swap-раздел), занимает изрядное время и, конечно, увеличивает значение swapped в статистике использования памяти.

Таким образом, будучи взяты в «статике», в отрыве от контекста, значения swap-out, swap-in, cached и swapped не говорят ни о чем. Система имеет право вытолкать в swap какую-то не слишком нужную информацию и даже имеет право кратковременно ошибиться в выборе. Однако, если данные параметры активно меняются в течение длительного времени, это будет тревожный признак.

Немного о вводе-выводе

Операции ввода-вывода в большинстве случаев осуществляются не через механизм отображения памяти, а операциями read()/write(). Это универсальный способ, который подходит не только для блочных устройств, но и для устройств последовательного доступа и для сетей передачи данных.

Данные, которые читаются и пишутся подобным образом, используют буферизацию ввода-вывода. В самом деле, к примеру – бывает, что программа способна накидать много данных и даже закончить свою работу (или прерваться на время), а медленное дисковое устройство все еще будет их принимать.

Для операционной системе, при наличии свободного места в памяти, выгоднее принять эти данные максимально возможной порцией и дать программе заниматься чем-то еще, пока другие процессы спокойно пишут на устройство.

В таких случаях из свободной оперативной памяти выделяется пространство под «буферы» (buffers), которые также могут раздуваться и освобождаться и считаются потенциально частью реально свободной оперативной памяти.

В то же время, так же как и с Cached-памятью, если система осуществляет массивный ввод-вывод, невозможность роста buffers будет риводить к тому, что процессы будут чаще ожидать окончания операций ввода-вывода, вместо выполнения полезной нагрузки.

Параметры vmstat

r – количество процессов, стоящих в очереди на выполнение процессором. В это количество не входят процесы, находящиеся в режимах ожидания различных событий (как то , ввод с терминала, дисковый и сетевой ввод-вывод и т.п.). Усредненное значение этой величины называется Load Average и его можно видеть в выводе команд top и uptime. Высокое значение r (и LA) говорит о том, что системе потенциально не хватает производительности.

b – количество процессов, заблокированных на операциях дискового ввода-вывода, которые требуют заверщения. Параметр обычно коррелирует с другим параметром – wa (I/O Wait, о котором ниже).

swpd – размер использованного swap (однако, не уверен, что после обратного swap-in, размер swpd должен уменьшиться).

free, buff, cache – составляющие свободной оперативной памяти, которые обсуждались выше.

si, so – swap-in и swap-out, количество page-in и page-out операций на swap-разделы.

bi, bo – число блоков полученных и отправленных в блочные устройства.

in – interrupts, число прерываний, обслуживаемых ядром. К примеру, дисковый ввод-вывод и прочая работа с аппаратными устройствами способна породить массу прерываний.

cs – context switches, фактчески – количество переключений между задачами.

us, sy, id, wa – user, system, idle, io wait, составляющие процессорного времени, в процентах. Для полностью загруженной системы адекватным считается распределение: 65-70%/30-35%/0-5%/0% (от сюда).

I/O Wait

Отдельного внимания заслуживает параметр wa – I/O Wait.

Он показывает время, которое процессы проводят в ожидании завершения дисковых операций, в то время, как если бы диски работали по-быстрее, процессы могли бы тоже ускориться.

Обычно, этот параметр может коррелировать с параметром «b» – число поцессов, ожидающих ввода вывода. Однако, к примеру, в ситуации, когда на ввод-вывод напрягается только один процесс, параметр «b» может и не подниматься слишком сильно.

Разбор полета

На приведенном в начале статьи примере vmstat, запущенного изначально на спокойной системе, можно видеть, как в момент начала операции dd, вызвавшей большой объем последовательного чтения, система затребовала максимум памяти под буферы ввода-вывода (buffers), для чего была задействована свободная память (free), освобождены кэши (cached), и даже что-то выгружено в swap (причем, судя по si, что-то было выгружено по ошибке).

sar

В реальной жизни часто бывает, что требуется посмотреть vmstat на агонизирующей системе, когда что-либо понять и исправить уже поздно, или даже уже после того, как ситему перезагрузили.

Это возможно. Достаточно заблаговременно установить в систему программу sar (в Debian/GNU Linux – пакет sysstat). Читайте мануалы.

Оригинал статьи: http://technotes.skycover.ru/?p=75 предоставлен участником проекта Zabber.ru.
cover:~# (sleep 3; dd if=/dev/xvda1 of=/dev/null)& vmstat 1
[1] 31169
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 1  0 115676  17096   4724  48888    0    1     2    12   11   30  0  0 97  2
 0  0 115676  16584   4724  48892    0    0     0     0   50   73  1  1 98  0
 0  0 115676  16336   4724  48896    0    0     0     0   28   60  0  0 100  0
 0  0 115676  16336   4724  48896    0    0     0     0   21   32  0  0 100  0
 1  2 116076   4992  40544  25796   32  404 84556  1140 3521 1518  7 34  0 58
 0  3 116076   4876  39732  26468    0    0 63204     0 2339 1346  5 18  0 76
 1  1 116076   4876  39756  25832    0    0 59272     0 2069 1482  4 18  0 78
 1  1 116076   4892  39756  25812    0    0 95360     0 3741 1913 11 36  0 51
Запись опубликована в рубрике Статьи с метками . Добавьте в закладки постоянную ссылку.

Комментарии запрещены.