문제
최근에 새 디스크를 설치하고 zpool을 만들었습니다.
/# zpool create morez /dev/sdb
잠시 동안 사용한 후에는 꽤 느리다는 것을 알았습니다.
/morez# fio --name rw --rw rw --size 10G
read: IOPS=19.6k, BW=76.6MiB/s (80.3MB/s)(5120MiB/66834msec)
write: IOPS=19.6k, BW=76.6MiB/s (80.3MB/s)(5120MiB/66834msec)
이 테스트는 실제 사용 사례와 상당히 유사합니다. 디스크에서 적당한 수 (~ 10k)의 이미지 (각각 ~ 2MiB)를 읽습니다. 디스크가 거의 비었을 때 한 번에 작성되었으므로 조각난 것으로 기대하지 않습니다.
비교를 위해 ext4를 테스트했습니다.
/# gdisk /dev/sdb
...
/# mkfs.ext4 -f /dev/sdb1 && mount /dev/sdb1 /mnt && cd /mnt
/mnt# fio --name rw --rw rw --size 10G
read: IOPS=48.3k, BW=189MiB/s (198MB/s)(5120MiB/27135msec)
write: IOPS=48.3k, BW=189MiB/s (198MB/s)(5120MiB/27135msec)
그리고 btrfs :
/# mkfs.btrfs -f /dev/sdb1 && mount /dev/sdb1 /mnt && cd /mnt
/mnt# fio --name rw --rw rw --size 10G
read: IOPS=51.3k, BW=201MiB/s (210MB/s)(5120MiB/25528msec)
write: IOPS=51.3k, BW=201MiB/s (210MB/s)(5120MiB/25528msec)
ZFS의 성능 문제를 일으키는 원인은 무엇이며 어떻게 더 빠르게 만들 수 있습니까?
솔루션 시도 실패
또한 내 디스크 ( Seagate ST1000DM003 )가 4096 바이트 물리 섹터를 사용하므로 zpool의 섹터 크기를 명시 적으로 설정하려고 시도했습니다 .
/# zpool create -o ashift=12 morez /dev/sdb
이것은 성능을 향상시키지 못했습니다.
/morez# fio --name rw --rw rw --size 10G
read: IOPS=21.3k, BW=83.2MiB/s (87.2MB/s)(5120MiB/61573msec)
write: IOPS=21.3k, BW=83.2MiB/s (87.2MB/s)(5120MiB/61573msec)
관측
이상하게도 zvol을 사용하면 성능이 뛰어납니다.
/# zfs create -V 20G morez/vol
/# fio --name rw --filename /dev/zvol/morez/vol --rw rw --size 10G
read: IOPS=52.7k, BW=206MiB/s (216MB/s)(5120MiB/24852msec)
write: IOPS=52.7k, BW=206MiB/s (216MB/s)(5120MiB/24852msec)
왜 이것이 zvol이 아닌 ZFS 파일 시스템에만 영향을 줍니까?
BTRFS에 대한 확장 테스트
의견에서 캐싱으로 인해 차이가 발생할 수 있다고 제안되었습니다. 추가 테스트 후, 나는 이것이 사실이라고 생각하지 않습니다. 컴퓨터의 메모리 양보다 btrfs 테스트 크기를 크게 늘 렸으며 성능은 여전히 ZFS보다 훨씬 큽니다.
/# mkfs.btrfs -f /dev/sdb1 && mount /dev/sdb1 /mnt && cd /mnt
/mnt# $ fio --name rw --rw rw --size 500G --runtime 3600 --time_based --ramp_time 900
read: IOPS=41.9k, BW=164MiB/s (172MB/s)(576GiB/3600003msec)
write: IOPS=41.9k, BW=164MiB/s (172MB/s)(576GiB/3600003msec)
시스템 정보
소프트웨어
- 아치 리눅스, 커널 버전 4.11.6
- Linux 0.6.5.10의 ZFS
- 피오 2.21
하드웨어
- 테스트 대상 드라이브 : Seagate ST1000DM003 , 6Gb / s SATA 포트에 연결
- 마더 보드 : Gigabyte X99-SLI
- 메모리 : 8GiB
ZFS 정보
다음은 fio를 실행하기 전에 ZFS 속성의 모습입니다. 이는 기본 설정으로 zpool을 생성 한 결과입니다.
# zpool get all morez
NAME PROPERTY VALUE SOURCE
morez size 928G -
morez capacity 0% -
morez altroot - default
morez health ONLINE -
morez guid [removed] default
morez version - default
morez bootfs - default
morez delegation on default
morez autoreplace off default
morez cachefile - default
morez failmode wait default
morez listsnapshots off default
morez autoexpand off default
morez dedupditto 0 default
morez dedupratio 1.00x -
morez free 928G -
morez allocated 276K -
morez readonly off -
morez ashift 0 default
morez comment - default
morez expandsize - -
morez freeing 0 default
morez fragmentation 0% -
morez leaked 0 default
morez feature@async_destroy enabled local
morez feature@empty_bpobj enabled local
morez feature@lz4_compress active local
morez feature@spacemap_histogram active local
morez feature@enabled_txg active local
morez feature@hole_birth active local
morez feature@extensible_dataset enabled local
morez feature@embedded_data active local
morez feature@bookmarks enabled local
morez feature@filesystem_limits enabled local
morez feature@large_blocks enabled local
# zfs get all morez
NAME PROPERTY VALUE SOURCE
morez type filesystem -
morez creation Thu Jun 29 19:34 2017 -
morez used 240K -
morez available 899G -
morez referenced 96K -
morez compressratio 1.00x -
morez mounted yes -
morez quota none default
morez reservation none default
morez recordsize 128K default
morez mountpoint /morez default
morez sharenfs off default
morez checksum on default
morez compression off default
morez atime on default
morez devices on default
morez exec on default
morez setuid on default
morez readonly off default
morez zoned off default
morez snapdir hidden default
morez aclinherit restricted default
morez canmount on default
morez xattr on default
morez copies 1 default
morez version 5 -
morez utf8only off -
morez normalization none -
morez casesensitivity sensitive -
morez vscan off default
morez nbmand off default
morez sharesmb off default
morez refquota none default
morez refreservation none default
morez primarycache all default
morez secondarycache all default
morez usedbysnapshots 0 -
morez usedbydataset 96K -
morez usedbychildren 144K -
morez usedbyrefreservation 0 -
morez logbias latency default
morez dedup off default
morez mlslabel none default
morez sync standard default
morez refcompressratio 1.00x -
morez written 96K -
morez logicalused 72.5K -
morez logicalreferenced 40K -
morez filesystem_limit none default
morez snapshot_limit none default
morez filesystem_count none default
morez snapshot_count none default
morez snapdev hidden default
morez acltype off default
morez context none default
morez fscontext none default
morez defcontext none default
morez rootcontext none default
morez relatime off default
morez redundant_metadata all default
morez overlay off default
답변
오래되었지만이 질문에 대한 답이 필요하다고 생각합니다.
fio
기본적으로 4KB 크기의 IOP 문제 대신 ZFS 데이터 세트는 기본적으로 128KB 레코드를 사용합니다. 이 불일치는 각 4K 쓰기가 전체 128K 레코드의 읽기 / 수정 / 쓰기를 유발한다는 것을 의미합니다.
반면에 ZVOL은 기본적으로 8K volblocksize를 사용합니다. 이것은 4K 쓰기가 8K 레코드의 읽기 / 수정 / 쓰기주기를 훨씬 더 작게 만들고, 운이 좋으면 두 개의 4K 쓰기를 단일 8K 쓰기로 통합 할 수 있음을 의미합니다 ( 읽기 / 수정 / 쓰기 가 전혀 필요 하지 않음 ).
ZFS 데이터 세트 레코드 화는 변경 될 수 있으며 zfs set recordize=8K <dataset>
,이 경우 ZVOL과 동등한 성능을 제공해야합니다. 그러나 비교적 큰 전송에 사용되는 경우 (OP는 이미지 인 경우 액세스 할 때마다 완전히 읽어야하는 약 2MB 파일을 말함) 큰 레코드 크기 / 볼 블록 크기 를 갖는 것이 좋습니다 . 때로는 기본 설정 (128K)보다 훨씬 큽니다.
답변
참고 : fio 작업이 부족하기 때문에 direct=1
( http://fio.readthedocs.io/en/latest/fio_doc.html#cmdoption-arg-direct ) 수행중인 I / O 양 (읽기 및 쓰기)이 캐시 될 수 있습니다. 운영 체제에 의해 결과가 왜곡되고 숫자가 인위적으로 높아집니다. 이 자체는 다음과 같이 더 복잡합니다.
- Linux의 ZFS는 지원하지 않으므로
O_DIRECT
(열리지 않음 ) 그렇지 않은 경우 버퍼 된 I / O로 조용히 되돌아갑니다 ( https://github.com/zfsonlinux/zfs/commit의 포인트 3 참조) / a584ef26053065f486d46a7335bea222cb03eeea ). - 경우에 따라 BTRFS 및 ext4는
O_DIRECT
버퍼 된 I / O로 대체됩니다 .
O_DIRECT
Linux O_DIRECT
에서는 힌트가 많기 때문에 여전히 버퍼링 된 I / O는 여전히 허용 된다는 것을 명심 하십시오 ( /programming//a/46377629/2732969 의 참조 섹션 참조 ).
캐시를 올바르게 우회 할 수없는 상황이라면 캐싱의 영향을 최소화하기 위해 충분히 큰 영역에서 충분한 I / O를 수행하는 것이 중요합니다 (물론 실제로 캐싱을 테스트하려는 경우는 제외) …