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). Читайте мануалы.
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
Pingback: vmstat, sar и первичная диагностика производительности | Zabber – пульс вашего сервера
Pingback: vmstat, sar и первичная диагностика производительности | Zabber - пульс вашего сервера