- Нагрузка на диски в Linux
- IOTOP
- IOSTAT
- Выявляем процессы с дисковой активностью в Linux
- Введение
- Определение количества записанных данных на дисковое устройство
- Определение программ, производящих запись на накопитель
- Определение файлов, в которые производится запись
- Определение накладных расходов файловой системы
- Как с fio проверить диски на достаточную производительность для etcd
- Краткое резюме всей статьи: fio и etcd
- Подробно о fio и etcd
- Несколько слов о WAL’ах etcd
- Оцениваем хранилище с помощью fio
- Почему мы выбрали fio и откуда узнали, как его настраивать
- Дело за вами
- P.S. от переводчика
Нагрузка на диски в Linux
Для измерения текущей нагрузки на диски (что происходит, кто куда копирует и прочее) в Linux можно использовать iotop (и здесь же lsof) и iostat. А для тестирования возможностей дисковой системы fio. Несмотря на то, что первое, о чем можно подумать в плане попугаев — это IOPS или же Мб/сек за чтение или запись, обратите внимание на время ожидания. Примерно как если бы вы стояли в очереди в кассу: вас обслужили бы за 2 минуты, но очередь может быть минут на 30. И со стороны наблюдателя ваш процесс обслуживания будет «висеть». Именно так могут ощущать себя клиенты сервера, если время ожидания будет намного превышать время выполнения конкретной задачи. Поэтому определение длинной очереди и задержек часто бывает более важным, чем знать, что ваш диск «вау, может писать 400 Мбит/с». Нагрузка на диск может оказаться в 4000 Мбит/с в течение длительных периодов времени и все это время клиенты сервера будут недовольны.
Я здесь пишу свой опыт, со своим видением и трактовкой. Пожалуйста, учитывайте это.
IOTOP
Посмотреть, какие процессы в настоящее время создают нагрузку на диск удобно смотреть командой iotop:
Здесь видно, что в данный момент mc что-то пишет (а в это время в другом окне я в самом деле копировал кучу файлов на usb-диск в Midnight Commander (он же mc).
Понять, что коипрует mc в данный момент можно узнать командой:
IOSTAT
Пример вывода iostat на незагруженной в данный момент старенькой системе из двух SATA HDD в soft raid 1 (зеркало) mdadm:
Команда выглядела так:
-x — расширенная статистика
-t — выводить время для каждой порции замеров
-m — результаты в Мбайт
5 — интервал замеров 5 секунд.
Если нужны не история, а динамика процесса, попробуйте так:
watch iostat -x -t -m 1 2
В этом выводе r/s и w/s это отправленные к устройству запросы на выполнение (IOPS, которые хотелось бы, чтобы устройство выполнило).
await — время, включающее ожидание выполнения запроса (как если бы вы встали в очередь в кассу и ждали бы, пока вас обслужат).
svctm — время, реально затраченное на выполнение запроса (время «на самой кассе»).
Для обычных SATA дисков нагрузка IOPS где-то до 100-130 вполне выполнимая. В момент проведения замеров запрошенная нагрузка была 40 IOPS, поэтому запрос практически в очереди и не стоял, его обслужили почти сразу (на «кассе» никого не было). Поэтому await практически равен svctm.
Другое дело, когда нагрузка на диск вырастает:
%iowait — простой процессора (время в процентах) от или процессоров, в то время пока обрабатывались запросы. Т.е. в среднем процессор отдыхал почти 50% времени.
%user — загруженность процессора пользовательскими приложениями. По этому параметру видно, например, что в данный период процессор был почти не занят. Это важно, т.к. может помочь отсечь подозрения в тормозах из-за процессора.
Замер сделан во время переноса большого количества писем из одной папки IMAP в другую. Особо обратите внимание на await и svctm. Налицо длинная очередь (отношение await к svctm). Дисковая система (или чипсет, или медленный контроллер SATA, или. ) не справляется с запрошенной нагрузкой (w/s).. Для пользователей в этот момент все выглядело просто — сервер тупит или даже завис.
Заранее проверить производительность дисков можно с помощью fio. Также можно примерно оценить на одной машине производительность дисков и понимать, какой уровень «в среднем по больнице» вы можете ожидать. Это, конечно же, не правильно, но оценить все же поможет. Глубже анализировать результаты, а, главное, методики тестов мне пока трудно.
# yum install fio
# apt-get install fio
В общем виде запуск выглядит так:
Файл your.cfg (название произвольное) может быть примерно таким (пример рабочего конфига для теста на чтение):
Буферизацию не используем (buffered=0), чтение не последовательное (rw=randread).
Во время выполнения этого теста (а выполняться тест может доооолго, надоест — Ctrl+C, результаты все равно будут) можно запустить iostat и посмотреть, что происходит:
Обратите внимание на отношение await к svctm: await/svctm = 32,11..11, т.е. можно считать 32. Это и есть iodepth из конфига your.cfg. Теперь проще понять смысл iodepth — мы указываем, насколько хотим в тесте имитировать длинную очередь заданий.
Я не стал ждать два дня, Ctrl+C и вот результат:
Получили 109 iops, что в принципе нормально, диск обычный, SATA.
Источник
Выявляем процессы с дисковой активностью в Linux
TL;DR: статья рассказывает об удобном, быстром и надежном способе определения Linux-программ, записывающих данные на диск, что помогает в выявлении большой или аномально частой нагрузки на дисковую подсистему, а также позволяет оценить накладные расходы файловой системы. Это особенно актуально для SSD в ПК, EMMC и Flash-памяти в одноплатных компьютерах.
В ходе написания статьи обнаружилось, что запись нескольких килобайт данных на файловую систему BTRFS приводит к записи 3 мегабайт реальных данных на диск.
Введение
После 7 месяцев использования нового SSD я решил проверить количество записанных данных, как их сообщает сам диск через SMART.
19.7 ТБ.
Всего за 7 месяцев я использовал 13% от гарантированного количества записанных данных, притом, что он настроен в соответствии с рекомендациями по выравниваю разделов и настройке ФС, swap у меня почти не используется, диски виртуальных машин размещены на HDD!
Это аномально большая цифра, такими темпами гарантийный TBW будет превышен раньше достижения 5-летнего срока гарантии диска. Да и не может мой компьютер писать по 93 гигабайта в сутки! Нужно проверить, сколько данных пишется на диск за 10 минут…
Total:
Writes Queued: 24,712, 2,237MiB
Writes Completed: 25,507, 2,237MiB
Write Merges: 58, 5,472KiB
Определение количества записанных данных на дисковое устройство
Мой SSD хранит количество записанных данных в параметре 241 Total_LBAs_Written, в логических блоках (LBA), а не в байтах. Размер логического блока в моём случае — 512 байт (его можно увидеть в выводе smartctl, в Sector Size). Чтобы получить байты, нужно умножить значение параметра на 512.
Программа skdump на моём SSD пытается интерпретировать значение Total_LBAs_Written как-то по-своему, из-за чего выводит 1296217.695 TB , что, очевидно, некорректно.
Чтобы узнать количество записываемой информации на уровне устройства, воспользуемся программой btrace из состава пакета blktrace . Она показывает как общую статистику за всё время работы программы, так и отдельные процессы и потоки (в т.ч. ядра), которые выполняли запись.
Запустите следующую команду, чтобы собрать информацию за 10 минут, где /dev/sdb — ваш диск:
btrace позволяет наглядно посмотреть реальное количество записанных данных, но понять, какие именно программы совершают запись, из её вывода сложно.
Определение программ, производящих запись на накопитель
Программа iotop покажет процессы, пишущие на диск, и размер записанных данных.
Наиболее удобный вывод обеспечивают следующие параметры:
В глаза бросается Firefox, записавший 283 мегабайта за несколько минут работы iotop.
Определение файлов, в которые производится запись
Информация о процессе, насилующим диск — хорошо, а пути, по которым производится запись — еще лучше.
Воспользуемся программой fatrace , которая отслеживает изменения файловой системы.
Fatrace не умеет показывать количество записанных данных вследствие использования довольно простого отслеживания факта обращения к файлам через inotify.
Из вывода видно, как хабр сохраняет мою статью в local storage браузера, пока я её пишу, а также расширение Group Speed Dial, которое, как удалось обнаружить именно с помощью fatrace, читает свои данные каждые 30 секунд. Именно читает, а не записывает: CW перед файлом говорит о том, что файл открывается на чтение и запись, с одновременным созданием файла, если он отсутствует (вызывается openat с флагом O_RDWR|O_CREAT), но не говорит, что в файл действительно писалась какая-либо информация.
На всякий случай, чтобы удостовериться в этом, воспользуемся strace, с фильтром на файловые системные вызовы:
Нет ни одного вызова write() , что говорит об отсутствии записи в файл.
Определение накладных расходов файловой системы
Большая разница в показаниях iotop и btrace натолкнула на мысль протестировать файловую систему путем ручной записи данных в файл и отслеживания показаний btrace.
Если полностью исключить запись на диск, загрузившись в emergency-режим systemd, и записать вручную пару байт данных в существующий файл, btrace на SSD с btrfs сообщает о записи 3 мегабайт реальных данных. Свежесозданная файловая система флешке размером в 8 ГБ записывает минимум 264 КиБ при записи одного байта.
Для сравнения, запись пары байт в файл на ext4 оканчивается записью 24 килобайтов данных на диск.
В 2017 году Jayashree Mohan, Rohan Kadekodi и Vijay Chidambaram провели исследование усиления записи разных файловых систем, их результаты для btrfs и ext4 при записи 4 КБ соотносятся с моими.
Источник
Как с fio проверить диски на достаточную производительность для etcd
Прим. перев.: эта статья — итоги мини-исследования, проведенного инженерами IBM Cloud в поисках решения реальной проблемы, связанной с эксплуатацией базы данных etcd. Для нас была актуальна схожая задача, однако ход размышлений и действий авторов может быть интересен и в более широком контексте.
Краткое резюме всей статьи: fio и etcd
Производительность кластера etcd сильно зависит от скорости хранилища, лежащего в его основе. Для контроля за производительностью etcd экспортирует различные метрики Prometheus. Одной из них является wal_fsync_duration_seconds . В документации к etcd говорится, что хранилище можно считать достаточно быстрым, если 99-й процентиль этой метрики не превышает 10 мс…
Если вы обдумываете возможность организации кластера etcd на машинах под управлением Linux и хотите проверить, достаточно ли быстры накопители (например, SSD), рекомендуем воспользоваться популярным тестером I/O под названием fio. Достаточно запустить следующую команду (директория test-data должна быть расположена в примонтированном разделе тестируемого накопителя):
Осталось лишь посмотреть на вывод и проверить, укладывается ли 99-й процентиль fdatasync в 10 мс. Если это так, значит ваш накопитель работает достаточно быстро. Вот пример вывода:
- В приведенном выше примере мы подстроили параметры —size и —bs под конкретный случай. Чтобы получить содержательный результат от fio , указывайте значения, подходящие для вашего сценария использования. О том, как их выбрать, будет рассказано ниже.
- Во время тестирования только fio нагружает дисковую подсистему. В реальной жизни вполне вероятно, что на диск будут писать и другие процессы (помимо тех, что связаны с wal_fsync_duration_seconds ). Подобная дополнительная нагрузка может привести к увеличению wal_fsync_duration_seconds . Другими словами, если 99-й процентиль, полученный по итогам тестирования с fio , лишь слегка меньше 10 мс, велика вероятность, что производительность хранилища недостаточна.
- Для теста вам понадобится версия fio не ниже 3.5, поскольку более старые версии не агрегируют результаты fdatasync в виде процентилей.
- Приведенный выше вывод представляет собой лишь небольшой отрывок от общего вывода fio .
Подробно о fio и etcd
Несколько слов о WAL’ах etcd
Как правило, базы данных используют упреждающую журнализацию (write-ahead logging, WAL). etcd это тоже касается. Обсуждение WAL выходит за рамки этой статьи, однако для наших целей нужно знать следующее: каждый член кластера etcd хранит WAL в постоянном хранилище. etcd записывает некоторые операции с key-value-хранилищем (например, обновления) в WAL, прежде чем выполнить их. Если узел упадет и перезапустится в промежутке между snapshot’ами, etcd сможет восстановить транзакции, проведенные с момента предыдущего snapshot’а, ориентируясь на содержимое WAL.
Таким образом, каждый раз, когда клиент добавляет ключ в KV-хранилище или обновляет значение существующего ключа, etcd добавляет описание операции в WAL, представляющий собой обычный файл в постоянном хранилище. Прежде чем продолжить работу, etcd ДОЛЖНА быть на 100% уверена, что запись в WAL действительно сохранена. Чтобы добиться этого в Linux, недостаточно использовать системный вызов write , поскольку сама операция записи на физический носитель может быть отложена. Например, Linux в течение некоторого времени может продержать WAL-запись в кэше ядра в памяти (например, в страничном кэше). Чтобы гарантировать, что данные записаны на носитель, после записи необходимо задействовать системный вызов fdatasync — именно так поступает etcd (как видно на примере следующего вывода strace ; здесь 8 — дескриптор файла WAL):
К сожалению, запись в постоянное хранилище занимает некоторое время. Затянувшееся выполнение вызова fdatasync может сказаться на производительности etcd. В документации к хранилищу указывается, что для достаточной производительности необходимо, чтобы 99-й процентиль продолжительности всех вызовов fdatasync при записи в файл WAL была меньше 10 мс. Есть и другие метрики, связанные с хранилищем, но в этой статье пойдет речь именно об этой.
Оцениваем хранилище с помощью fio
Оценить, подходит ли некое хранилище для использования с etcd, можно с помощью утилиты fio — популярного тестера I/O. Учитывайте, что дисковый ввод-вывод может происходить по-разному: sync/async, множество различных классов системных вызовов и т.п. Оборотная сторона медали заключается в том, что fio чрезвычайно сложна в использовании. У утилиты множество параметров, и различные комбинации их значений приводят к совершенно разным результатам. Чтобы получить вменяемую оценку в случае etcd, вы должны убедиться, что нагрузка на запись, генерируемая fio, максимально походит на нагрузку etcd при записи в WAL-файлы:
- Это означает, что генерируемая fio нагрузка, по крайней мере, должна представлять собой серию последовательных записей в файл, где каждая операции записи состоит из системного вызова write , за которым следует fdatasync .
- Чтобы включить последовательную запись, необходимо указать флаг —rw=write .
- Чтобы fio писала с использованием вызовов write (а не других системных вызовов — например, pwrite ), используйте флаг —ioengine=sync .
- Наконец, флаг —fdatasync=1 гарантирует, что за каждым write следует fdatasync .
- Два других параметра в нашем примере: —size и —bs — могут меняться в зависимости от конкретного сценария использования. В следующем разделе будет описана их настройка.
Почему мы выбрали fio и откуда узнали, как его настраивать
Эта заметка появилась из реального случая, с которым мы столкнулись. У нас был кластер на Kubernetes v1.13 с мониторингом на Prometheus. В качестве хранилища для etcd v3.2.24 выступали твердотельные накопители. Метрики etcd показывали слишком высокие задержки fdatasync , даже когда кластер простаивал. Нам эти метрики казались весьма сомнительными, и мы не были уверены в том, что именно они представляют. Вдобавок, кластер состоял из виртуальных машин, поэтому не получалось сказать, задержка была связана с виртуализацией или во всем виноваты SSD.
Кроме того, мы рассматривали различные изменения в конфигурации аппаратного и программного обеспечения, поэтому требовался способ их оценки. Конечно, можно было бы запустить etcd в каждой конфигурации и посмотреть на соответствующие метрики Prometheus, но это потребовало бы значительных усилий. Нам же был нужен простой способ, позволяющий оценить конкретную конфигурацию. Мы хотели проверить свое понимание метрик Prometheus, поступающих от etcd.
Для этого требовалось решить две проблемы:
- Во-первых, как выглядит I/O-нагрузка, генерируемая etcd при записи в файлы WAL? Какие системные вызовы используются? Каков размер блоков записи?
- Во-вторых, допустим, ответы на вышеперечисленные вопросы у нас есть. Как воспроизвести соответствующую нагрузку с fio ? Ведь fio — чрезвычайно гибкая утилита с обилием параметров (в этом легко убедиться, например, здесь — прим. перев.).
Мы решили обе проблемы с помощью одного и того же подхода, опирающегося на команды lsof и strace :
- С помощью lsof можно просмотреть все файловые дескрипторы, используемые процессом, а также файлы, к которым они относятся.
- С помощью strace можно анализировать уже запущенный процесс или запустить процесс и понаблюдать за ним. Команда выводит все системные вызовы, совершенные данным процессом и, при необходимости, его потомками. Последнее важно для процессов, который форкается, и etcd — один из таких процессов.
Первое, что мы сделали, — использовали strace для изучения сервера etcd в кластере Kubernetes, пока тот простаивал.
Так было обнаружено, что блоки записи в WAL очень плотно сгруппированы, размер большинства лежал в диапазоне 2200-2400 байт. Именно поэтому в команде в начале этой статьи используется флаг —bs=2300 ( bs — размер в байтах каждого блока записи в fio ).
Обратите внимание, что размер блоков записи etcd может варьироваться в зависимости от версии, deployment’а, значений параметров и т.д. — это влияет на продолжительность fdatasync . Если у вас похожий сценарий использования, проанализируйте с помощью strace свои процессы etcd, чтобы получить актуальные значения.
Затем, чтобы получить четкое и всеобъемлющее представление о работе etcd с файловой системой, мы запустили ее из-под strace с флагами -ffttT . Это позволило охватить процессы-потомки и записать вывод каждого в отдельный файл. Кроме того, были получены подробные сведения о моменте старта и длительности каждого системного вызова.
Мы также воспользовались командой lsof , чтобы подтвердить свое понимание вывода strace в плане того, какой файловый дескриптор для какой цели использовался. Получился вывод strace , похожий на тот, что приведен выше. Статистические манипуляции со временами синхронизации подтвердили, что метрика wal_fsync_duration_seconds от etcd соответствует вызовам fdatasync с дескрипторами файлов WAL.
Чтобы сгенерировать с помощью fio рабочую нагрузку, аналогичную нагрузке от etcd, была изучена документация утилиты и подобраны параметры, подходящие нашей задаче. Мы убедились в том, что задействованы нужные системные вызовы, и подтвердили их продолжительность, запустив fio из strace (как это было сделано в случае etcd).
Особое внимание было уделено определению значения параметра —size . Он представляет собой общую нагрузку I/O, генерируемую утилитой fio. В нашем случае это полное число байтов, записанное на носитель. Оно прямо пропорционально числу вызовов write (и fdatasync ). Для определенного bs количество вызовов fdatasync равно size / bs .
Поскольку нас интересовал процентиль, мы стремились к тому, чтобы число проб было достаточно большим для статистической значимости. И решили, что 10^4 (что соответствует размеру в 22 Мб) будет достаточно. Меньшие значения параметра —size давали более выраженный шум (например, вызовы fdatasync , которые занимают гораздо больше времени, чем обычно, и влияют на 99-й процентиль).
Дело за вами
В статье показано, как с помощью fio можно оценить, является ли достаточно быстрым носитель, предназначенный для использования с etcd. Теперь дело за вами! Исследовать виртуальные машины с хранилищем на базе SSD можно в сервисе IBM Cloud.
P.S. от переводчика
С готовыми примерами использования fio для решения других задач можно ознакомиться в документации или напрямую в репозитории проекта (там их представлено намного больше, чем упоминается в документации).
Источник