
Я пытаюсь измерить задержки ввода-вывода на диске запущенного процесса, чтобы построить гистограмму.
Я мог бы сделать это с помощью DTrace в операционных системах, которые его предоставляют (например, как вэта статья Joyent), но мое приложение работает в Linux. Первой моей мыслью было попробовать perf
, и я могу получить счетчики, но не могу найти способ получить дельты времени. Я могу получить дельты времени с помощью strace
(например strace -e read -T
), но я не уверен, смогу ли я ограничить трассировку дисковым вводом-выводом (эта система также имеет загруженный сетевой интерфейс).
Есть ли способ сделать это в Linux?
решение1
Это на самом деле сложно. Но есть подсказки:
Узнайте о SystemTap, это аналог DTrace для Linux. Я думаю, у них даже может быть пример скрипта для подобной задачи.
Учитьсяblktrace. Теоретически вы можете разобрать его вывод. Это будет больше задержки устройства (время обслуживания), чемвремя откликапрограмма начинается
read()
.
Да strace
может быть неуместным, так как он будет отслеживать все (все системные вызовы, даже если вы используете -e
фильтр) и будет загружать сервер и значительно замедлять процесс. Perf
очень непонятный инструмент, у вас могут быть моменты, когда вы думаете, что понимаете его вывод, но на самом деле это не так, и его набор функций сильно зависит от версии ядра. В основном и в настоящее время perf
подходит для измеренияпроцессорное время(циклы), и [пока] непригодны для измерениявремя отклика(что вам на самом деле нужно). Я слышал, что они хотели реализовать что-то, чтобы облегчить это, так что в последних разрабатываемых ядрах что-то может быть. (Посмотрите также perf-scripts ( perf script -l
), если вы будете исследовать дальше.)
Может быть, вы сможете получить что-то отftrace. Прочитать эту статьюhttp://lwn.net/Articles/370423/(И это длявступление.) Как я вижу, вы можете ограничить ftracing
pid
функцией и, а затем выполнить трассировку чем-то вродеsys_read
. Я попробовал это в качестве примера для вас:# mount -t debugfs debugfs /sys/kernel/debug # if it's not already mounted # cd /sys/kernel/debug/tracing # echo $$ > set_ftrace_pid # pid of process to trace # echo sys_read sys_write > set_ftrace_filter # echo function_graph > current_tracer # head trace # tracer: function_graph # # CPU DURATION FUNCTION CALLS # | | | | | | | 0) 8.235 us | sys_write(); 0) 3.393 us | sys_write(); 0) ! 459859.3 us | sys_read(); 0) 6.289 us | sys_write(); 0) 8.773 us | sys_write(); 0) ! 1576469 us | sys_read();
решение2
Если вас интересует только количество вызовов «чтения» или «записи» для блокирования устройствэто стандартная операционная процедура Red Hat для определения того, что.
Используя функцию блочного дампа и немного скриптинга, можно собрать высокоуровневый обзор действий ввода-вывода, которые производят процессы. Для этого выполните следующее:
Отключите ведение журнала системы на короткий период времени (чтобы это не мешало сбору данных):
# остановка службы syslog # echo 1 > /proc/sys/vm/block_dump
Дождитесь возникновения проблемы с высоким значением iowait, после чего снова включите syslog (или rsyslog, если он используется) и отключите дамп блока:
# запуск службы syslog # echo 0 > /proc/sys/vm/block_dump
Используя следующую команду, проанализируйте вывод dmesg на предмет действий READ/WRITE/dirtied, выполняемых определенными процессами:
# dmesg | awk '/(ЧТЕНИЕ|ЗАПИСЬ|загрязнено)/ {activity[$1]++} END {for (x в активности) print x, activity[x]}'| sort -nr -k 2,2| head -n 10
kjournald(1425): 5984 kjournald(3681): 1269 pdflush(27301): 725 iostat(2913): 134 crond(26919): 61 crond(28985): 60 crond(7026): 54 sshd(28175): 50 sshd(15388): 50 nautilus(24498): 46
В примере вывода выше показаны 10 основных процессов, которые выдавали операции READ, WRITE и dirtied во время выполнения дампа блока. Используя эти данные, можно собрать высокоуровневый обзор количества операций, которые выдают процессы, и это может помочь определить, вносит ли отдельный процесс большой вклад в iowait.
Также существует несколько инструментов командной строки, таких как atop и iotop, которые предоставляют статистику iowait для каждого процесса и могут быть запущены как часть скрипта (то есть у них есть пакетные режимы, которые могут выполнять одну итерацию для определенных PID).
РЕДАКТИРОВАТЬ: Проведя больше исследований, похоже, что вы можетеполучить iowait для каждого процесса из /proc/$pid/stat(поиск по запросу «Агрегированные задержки ввода-вывода блоков»)