
히스토그램을 만들기 위해 실행 중인 프로세스의 디스크 IO 대기 시간을 측정하려고 합니다.
이를 제공하는 운영 체제에서 DTrace를 사용하여 이 작업을 수행할 수 있습니다(예:이 Joyent 논문), 하지만 내 애플리케이션은 Linux에서 실행되고 있습니다. 내 첫 번째 생각은 시도하는 것이 perf
었고 카운터를 얻을 수 있지만 시간 델타를 얻을 수 있는 방법을 찾을 수 없습니다. strace
(예: ) 을 사용하여 시간 델타를 얻을 수 있지만 strace -e read -T
추적을 디스크 IO로 제한할 수 있는지 확실하지 않습니다(이 시스템에는 사용량이 많은 네트워크 인터페이스도 있습니다).
리눅스에서 이것을 할 수 있는 방법이 있나요?
답변1
이것은 실제로 복잡합니다. 하지만 힌트가 있습니다:
SystemTap에 대해 알아보세요. 이것은 DTrace의 Linux 아날로그입니다. 비슷한 작업에 대한 예제 스크립트가 있을 수도 있다고 생각합니다.
배우다블록 추적. 이론적으로는 출력을 구문 분석할 수 있습니다. 이는 장치 지연 시간(서비스 시간)이 더 길어집니다.응답 시간프로그램 타세요
read()
.
예는 strace
모든 것(필터를 사용하는 경우에도 모든 syscall)을 추적 -e
하고 서버와 느린 프로세스를 상당히 로드하므로 적절하지 않을 수 있습니다. Perf
매우 모호한 도구이므로 출력을 이해했다고 생각하지만 실제로는 이해하지 못한 순간이 있을 수 있으며 기능 세트는 커널 버전에 따라 크게 달라집니다. 기본적으로 현재 perf
측정에 적합합니다.CPU 시간(사이클), [아직] 측정에 적합하지 않음응답 시간(실제로 필요한 것). 이를 쉽게 하기 위해 무언가를 구현하고 싶다고 들었습니다. 따라서 최근 개발 커널에는 뭔가가 있을 수 있습니다. ( perf script -l
추가로 조사하려면 성능 스크립트( )도 살펴보십시오 .)
어쩌면 당신은 뭔가를 얻을 수 있을 것입니다ftrace. 이 기사를 읽어보세요http://lwn.net/Articles/370423/(그리고 이것은소개.) 내가 볼 수 있듯이 ftracing을
pid
및 function으로 제한한 다음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의 SOP입니다..
블록 덤프 기능과 약간의 스크립팅을 사용하면 프로세스가 생성하는 I/O 작업에 대한 높은 수준의 개요를 수집할 수 있습니다. 이렇게 하려면 다음을 완료하세요.
짧은 시간 동안 시스템 로깅을 비활성화합니다(데이터 캡처를 방해하지 않도록).
# 서비스 syslog 중지 # echo 1 > /proc/sys/vm/block_dump
syslog(또는 이를 사용하는 경우 rsyslog)를 다시 활성화한 후 높은 iowait 문제가 발생할 때까지 기다렸다가 블록 덤프를 비활성화합니다.
# 서비스 syslog 시작 # echo 0 > /proc/sys/vm/block_dump
다음 명령을 사용하여 특정 프로세스에서 실행되는 읽기/쓰기/더러운 작업에 대한 dmesg 출력을 구문 분석합니다.
# dmesg | awk '/(READ|WRITE|dirtied)/ {활동[$1]++} END {for (x in 활동) 인쇄 x, 활동[x]}'| 정렬 -nr -k 2,2| 머리 -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 (50 Sshd). 15388):50 노틸러스(24498):46
위의 출력 예는 블록 덤프가 실행되는 동안 READ, WRITE 및 dirty 작업을 실행한 상위 10개 프로세스를 보여줍니다. 이 데이터를 사용하면 실행 중인 작업 프로세스 수에 대한 높은 수준의 개요를 수집할 수 있으며 단일 프로세스가 iowait에 크게 기여하는지 확인하는 데 도움이 될 수 있습니다.
프로세스별 iowait 통계를 제공하고 스크립트의 일부로 실행될 수 있는 atop 및 iotop과 같은 여러 명령줄 도구도 있습니다(특정 PID에 대해 단일 반복을 수행할 수 있는 배치 모드가 있음을 의미).
편집하다: 좀 더 연구해보면 그럴 수 있을 것 같다./proc/$pid/stat에서 프로세스별 iowait 가져오기("집계 블록 I/O 지연" 검색)