sudo dd if=/dev/sda of=/dev/null bs=1M iflag=direct
atopsar -d 5 # in a second terminal
top # in a third terminal
왜냐하면. . . 결과 atopsar
:
19:18:32 disk busy read/s KB/read writ/s KB/writ avque avserv _dsk_
...
19:16:50 sda 18% 156.5 1024.0 0.0 0.0 5.0 1.15 ms
19:16:55 sda 18% 156.3 1024.0 0.0 0.0 4.9 1.15 ms
...
보고된 디스크 사용률("사용 중")이 100%보다 훨씬 낮은 이유는 무엇입니까?
top
해당 프로세스는 dd
CPU의 3% 이하만 사용한다고 합니다 . 시스템 CPU의 하드웨어 및 소프트웨어 인터럽트(및) 사용량에 대한 전체 보고서도 제공되며 top
1% 미만을 보여줍니다. 4개의 CPU(각각 2개의 스레드가 있는 2개의 코어)가 있습니다.hi
si
/dev/sda
SATA 하드디스크 입니다. SSD도 아니고 하이브리드 SSHD 드라이브도 아닙니다. 읽기 속도는 초당 150MB를 초과할 수 없습니다 :-). 따라서 결과의 이 부분은 의미가 있습니다. 156 읽기/초 * 1024KB/읽기 = 156MB/초
커널 버전은 5.0.9-200.fc29.x86_64
(Fedora Workstation 29)입니다. IO 스케줄러는 mq-deadline
커널 버전 5.0부터 시작하여 다중 대기열 블록 계층을 사용합니다. 단일 대기열 블록 레이어가 제거되었기 때문입니다 :-).
디스크 사용률 수치는 다음 중 하나를 기준으로 계산 atopsar -d
됩니다 .atop
커널 iostat 필드. 링크된 문서에는 "필드 10 - I/O 수행에 소요된 밀리초 수"가 언급되어 있습니다. 더 자세한 정의가 있지만, 언급된 기능이 다중 대기열 블록 계층에 여전히 존재하는지 확실하지 않습니다. 내가 아는 한, atopsar -d
둘 다 atop
사용유니버셜 코드sar -d
iostat -x
이 필드를 읽어보세요 10. ( // 이 필드 도 사용한다고 생각합니다 mxiostat.py
)
추가 테스트
변형 2: 로 변경하되 bs=512k
유지합니다 iflag=direct
.
dd if=/dev/sda of=/dev/null bs=512k iflag=direct
19:18:32 disk busy read/s KB/read writ/s KB/writ avque avserv _dsk_
...
19:18:00 sda 35% 314.0 512.0 0.0 0.0 2.1 1.12 ms
19:18:05 sda 35% 313.6 512.0 0.2 4.0 2.1 1.11 ms
변형 3: 을 사용 bs=1M
하지만 제거는 iflag=direct
약 dd
10%의 CPU와 35%의 디스크를 사용합니다.
dd if=/dev/sda of=/dev/null bs=1M
19:18:32 disk busy read/s KB/read writ/s KB/writ avque avserv _dsk_
...
19:21:47 sda 35% 242.3 660.2 0.0 0.0 5.4 1.44 ms
19:21:52 sda 31% 232.3 667.8 0.0 0.0 9.5 1.33 ms
이러한 결과를 재현하는 방법 - 중요한 세부정보
실행되는 마지막 테스트를 참고하세요.dd
아니요 iflag=direct
좀 돼지같네요. 시스템(마우스 커서)이 10초 이상 정지되는 것을 본 적이 있습니다. 스왑을 비활성화하더라도. (RAM 채우기 테스트이득/캐시. 비활성 LRU 목록을 채우고 있습니다. 처리가 완료되면 캐시된 비활성 페이지가 상대적으로 빠르게 제거될 것이라고 생각합니다. 동시에 디스크는 순차 읽기로 인해 페이지를 처리해야 할 때 시간이 더 오래 걸립니다. 이 상황이 얼마나 나쁜지는 커널이 결국 활성 LRU 목록도 뒤집는지 아니면 너무 많이 축소하는지에 따라 달라질 수 있습니다. 즉, 현재 상황은 어떠한가?"최첨단 사례와 다양한 최적화를 포착하기 위해 일부 수정과 다양한 알고리즘의 혼합"귀하의 경우에는 작동합니다).
이것정밀한첫 번째 테스트 결과는 재현하기 어렵습니다.
때로는 대신 KB/read
으로 표시됩니다 . 이 경우 다른 결과는 의 결과와 더 비슷해 보입니다 . 무엇보다도 디스크 사용률이 약 20%가 아닌 약 35%로 나타났습니다. 두 경우 모두 내 질문은 유효합니다.512
1024
bs=512k
이 동작을 이해하려면 여기를 참조하세요.내 IO 요청 크기가 약 512K로 제한되는 이유는 무엇입니까?
답변1
이는 커널 버전 5.0의 변경 결과입니다.
블록: part_round_stats를 제거하고덜 정확한 계산으로 전환
우리는 이것을 CPU당 in_flight 카운터로 변환하고 싶습니다.
part_round_stats 함수에는 각 jiffy에 대한 in_flight 카운터가 필요하며 jiffy당 모든 CPU 변수를 합산하는 비용이 너무 높으므로 제거해야 합니다. part_round_stats는 time_in_queue 및 io_ticks라는 두 개의 카운터를 계산하는 데 사용됩니다.
time_in_queue는 I/O 종료 시 I/O 지속 시간을 추가하여 part_round_stats 없이 계산할 수 있습니다. (이 값은 진행 중인 I/O의 시간이 계산되지 않는다는 점을 제외하면 이전에 계산된 값과 거의 동일합니다. ).
io_ticks는 I/O가 시작되거나 종료되고 jiffies 값이 변경될 때 값을 늘려 대략적으로 계산할 수 있습니다. I/O에 1초 미만이 소요되는 경우 이 값은 이전에 계산된 값만큼 정확합니다. I/O가 1초 이상 걸리는 경우 io_ticks는 이전에 계산된 값보다 뒤쳐질 수 있습니다.
( io_ticks
을 위한부분 통계 표시(),공급커널 IO 통계"필드 10 - I/O 수행에 소요된 밀리초 수"의 경우. )
이것은 내 결과를 잘 설명합니다. Fedora 커널 구성에서 "순간"1ms입니다. 커밋하는 대규모 읽기 IO는 dd
1~2초 이상 기다릴 수 있을 것으로 예상됩니다. 특히 오래된 기계식 HDD를 사용하는 시스템에서는 더욱 그렇습니다.
이전 커널 시리즈 4.20.x로 돌아가면 올바른 디스크 사용률이 표시됩니다.
$ uname -r
4.20.15-200.fc29.x86_64
$ atopsar -d 5
...
13:27:19 disk busy read/s KB/read writ/s KB/writ avque avserv _dsk_
13:28:49 sda 98% 149.4 1024.0 13.0 5.3 2.2 6.04 ms
13:28:54 sda 98% 146.0 1024.0 7.2 5.7 1.5 6.38 ms
cfq
이 오래된 커널은 기본적으로 기존 단일 대기열 블록 계층과 IO 스케줄러를 사용합니다. IO 스케줄러를 사용할 때의 결과는 동일합니다 deadline
.
업데이트: 커널 5.7부터 이 근사치가 조정되었습니다. 질문의 명령은 다시 디스크 사용률을 100%로 표시합니다. 좀 더 복잡한 워크로드에서는 새로운 근사치가 충돌할 것으로 예상됩니다(아직 눈치채지는 못했지만).
block/diskstats: 느린 디스크에 대한 io_ticks의 보다 정확한 근사치
현재 jiffies 카운터가 변경된 경우 io_ticks의 대략적인 값은 요청의 시작과 끝마다 1씩 증가합니다. 이는 1초보다 짧은 요청이나 1초마다 하나의 요청이 시작/종료되는 경우에 유용합니다.
디스크가 한 번에 하나의 요청만 수행하고 해당 요청이 2지피보다 긴 경우 첫 번째와 마지막 지피만 계산됩니다.
수정은 간단합니다. 요청이 끝나면 단 하나의 jiffy 대신 io_ticks에 대한 마지막 업데이트 이후 전달된 io_ticks jiffy를 추가합니다.
예: 일반 하드 디스크가 임의 읽기 4k 요청을 수행하는 데 걸리는 시간은 약 12ms입니다.
fio --name=test --filename=/dev/sdb --rw=randread --direct=1 --runtime=30 &
iostat -x 10 sdb
패치 전후에 iostat의 "%util"이 8,43% -> 99,99%로 변경된 점에 유의하세요.
앞으로:
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sdb 0,00 0,00 82,60 0,00 330,40 0,00 8,00 0,96 12,09 12,09 0,00 1,02 8,43
뒤쪽에:
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sdb 0,00 0,00 82,50 0,00 330,00 0,00 8,00 1,00 12,10 12,10 0,00 12,12 99,99
이제 io_ticks는 요청의 시작과 끝 사이의 시간을 줄이지 않지만 대기열 깊이가 1보다 큰 경우 인접한 시작 사이의 일부 I/O 시간이 손실될 수 있습니다.
로드 추정의 경우 "%util"은 평균 대기열 길이만큼 유용하지는 않지만 디스크 대기열이 완전히 비어 있는 빈도를 명확하게 보여줍니다.
수정: 5b18b5a("차단: part_round_stats를 제거하고 덜 정확한 계산으로 전환")
승인: Konstantin Khlebnikov <[이메일 보호됨]>
검토자: 레이 밍<[이메일 보호됨]>
서명자: Jens Axboe <[이메일 보호됨]>