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