fio seq_writes가 dd보다 훨씬 빠른 이유는 무엇입니까?

fio seq_writes가 dd보다 훨씬 빠른 이유는 무엇입니까?

이해하기 위해 몇 가지 어리석은 테스트를 실행하고 있는 zfs 서버가 있는데, 이것이 나를 혼란스럽게 합니다.

컨텍스트: - FreeBSD 11.2, 압축이 활성화된 ZFS, SAS HDD, RAIDz2, 768GB RAM.

두 명령 모두 FreeBSD 서버에서 직접 실행됩니다.

# time dd if=/dev/random of=./test_file bs=128k count=131072 
131072+0 records in
131072+0 records out
17179869184 bytes transferred in 135.191596 secs (127077937 bytes/sec)
0.047u 134.700s 2:15.19 99.6%   30+172k 4+131072io 0pf+0w

# #The result file size:
# du -sh test_file 
  16G   test_file

이는 무작위 데이터가 포함된 16GiB 파일을 약 135초 만에 처리할 수 있었음을 보여줍니다. 117MiB/초

이제 사용해 보려고 합니다페오,

# fio --name=seqwrite --rw=write --bs=128k --numjobs=1 --size=16G --runtime=120 --iodepth=1 --group_reporting
seqwrite: (g=0): rw=write, bs=(R) 128KiB-128KiB, (W) 128KiB-128KiB, (T) 128KiB-128KiB, ioengine=psync, iodepth=1
fio-3.6
Starting 1 process
seqwrite: Laying out IO file (1 file / 16384MiB)
Jobs: 1 (f=1): [W(1)][100.0%][r=0KiB/s,w=2482MiB/s][r=0,w=19.9k IOPS][eta 00m:00s]
seqwrite: (groupid=0, jobs=1): err= 0: pid=58575: Wed Jul 25 09:38:06 2018
  write: IOPS=19.8k, BW=2478MiB/s (2598MB/s)(16.0GiB/6612msec)
    clat (usec): min=28, max=2585, avg=48.03, stdev=24.04
     lat (usec): min=29, max=2586, avg=49.75, stdev=25.19
   bw (  MiB/s): min= 2295, max= 2708, per=99.45%, avg=2464.33, stdev=124.56, samples=13
   iops        : min=18367, max=21664, avg=19714.08, stdev=996.47, samples=13
---------- Trimmed for brevity -------------
Run status group 0 (all jobs):
  WRITE: bw=2478MiB/s (2598MB/s), 2478MiB/s-2478MiB/s (2598MB/s-2598MB/s), io=16.0GiB (17.2GB), run=6612-6612msec

이제 처리량이 2478MiB/s에 도달했습니다. 또한 임의의 데이터와 함께 동일한 16GiB 파일을 사용합니다.

왜 그렇게 큰 차이가 있습니까? 제가 이해한 바에 따르면 dd 명령은 createcall을 사용하여 파일을 생성한 다음 실행해야 하며 open호출 write은 열려 있는 파일에 임의의 데이터를 기록합니다. 마지막으로 파일이 있습니다 close. ZFS 기본 레코드 크기와 일치하도록 128K의 블록 크기를 선택했습니다.

fio 테스트는 통화만 측정해야 write하지만 다른 모든 것은 동일합니다. 처리량 차이가 왜 그렇게 큰가요?

더욱 혼란스러운 점은 fio에게 50% 압축으로 파일을 생성하도록 요청하면 처리량이 847MiB/s로 떨어진다는 것입니다. 압축에는 CPU 작업이 포함되어 처리량이 감소한다는 것을 알고 있지만 데이터 양의 거의 절반을 기록하여 이를 상쇄하고 싶습니다. 왜 그렇게 큰 영향을 미치는지 아시나요?

50% 압축으로 fio를 실행하는 명령:

 fio --name=seqwrite --rw=write --bs=128k --numjobs=1 --size=16G --runtime=60 --iodepth=1 --buffer_compress_percentage=50 --buffer_pattern=0xdeadbeef --group_reporting

답변1

몇 가지 맥락을 강조하기 위해 귀하의 질문을 재구성하겠습니다.

왜?

fio --name=seqwrite --rw=write --bs=128k --numjobs=1 --size=16G --runtime=120 --iodepth=1 --group_reporting

보다 빠른

time dd if=/dev/random of=./test_file bs=128k count=131072 

768GB RAM, SAS HDD 및 ZFS가 압축이 활성화된 RAIDZ2로 구성된 FreeBSD 11.2 시스템에서?

가장 큰 차이점은 fio가 테스트를 시작하기 전에 파일을 미리 생성한다는 것입니다.

seqwrite: Laying out IO file (1 file / 16384MiB)

대신 dd파일 확장자 쓰기가 발생할 수 있습니다(이로 인해 메타데이터 업데이트가 발생함). 또한 RAM(768G)이 너무 많지만(16G) 이에 비해 쓰는 데이터가 거의 없으므로 쓰기가 RAM에 보관될 가능성이 높습니다(실제로 훨씬 나중에 디스크에 기록되지 않음). fio파일이 미리 만들어져 있고 각 I/O에 대해 수정해야 하는 파일 메타데이터가 거의 없는 경우 이런 일이 발생할 수 있습니다 . 적어도 기록된 모든 데이터가 커널에서 다시 기록될 때 작업이 끝날 때까지 완료되었다고 말하지 않도록 fio에게 지시할 수 있습니다.end_fsync=1.

(참고: 디스크가 수행할 수 있는 것으로 알고 있는 것보다 훨씬 낮은 완료 지연 시간을 보면 I/O가 버퍼링 중이라는 미묘한 힌트가 있습니다.

clat(usec): 최소=28, 최대=2585, 평균=48.03, stdev=24.04

회전 디스크가 실제로 28마이크로초 안에 I/O 작업을 완료할 수 있습니까? 그렇지 않다면 아마도 어딘가에 버퍼링되어 있을 것입니다)

마침내,fio는 기본적으로 후속 블록에서 동일한 패턴을 재사용합니다.. 압축이 수행되므로 fio처리량을 더욱 향상시킬 수 있습니다(그러나 이는 ZFS 레코드 크기와 같은 요인에 따라 달라집니다). 이를 확인하려면 fio에게 버퍼를 압축할 수 없게 만들고(결국 켜짐 refill_buffers) 처리량이 떨어지는지 확인하라고 지시합니다(귀하의 경우에는 그렇습니다).

너무 깁니다. 귀하가 제공 한 fio및 명령은 dd동일한 것을 테스트하지 않습니다. 파일이 이미 올바른 크기로 존재하는지 여부, 작성 중인 데이터가 얼마나 압축 가능한지, 데이터가 모두 다시 기록되었는지 확인하지 않고 너무 적은 데이터를 기록하여 커널 버퍼링을 고려하고 있는지 여부 등의 사항에 주의를 기울여야 합니다. 디스크.

관련 정보