ทำไม ZFS ถึงช้ากว่า ext4 และ btrfs มาก


11

ปัญหา

ฉันเพิ่งติดตั้งดิสก์ใหม่และสร้าง 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) ของภาพ (ประมาณ 2 MiB) จากดิสก์ พวกเขาเขียนทั้งหมดในครั้งเดียวเมื่อดิสก์ว่างเปล่าเป็นส่วนใหญ่ดังนั้นฉันไม่คาดหวังให้แยกส่วน

สำหรับการเปรียบเทียบฉันทดสอบ 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 และฉันจะทำให้เร็วขึ้นได้อย่างไร

ความพยายามในการแก้ปัญหาล้มเหลว

ฉันยังพยายามตั้งค่าขนาดเซกเตอร์สำหรับ zpool อย่างชัดเจนเนื่องจากดิสก์ของฉัน ( Seagate ST1000DM003 ) ใช้เซกเตอร์ฟิสิคัล 4096 ไบต์:

/# 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)

ทำไมสิ่งนี้ถึงกระทบต่อระบบไฟล์ ZFS เท่านั้นและไม่ใช่ zvols?

การทดสอบเพิ่มเติมสำหรับ 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)

ข้อมูลระบบ

ซอฟต์แวร์

  • Arch Linux, เคอร์เนลเวอร์ชั่น 4.11.6
  • ZFS บน Linux 0.6.5.10
  • fio 2.21

ฮาร์ดแวร์

  • ไดร์ฟกำลังทดสอบ: Seagate ST1000DM003เชื่อมต่อกับพอร์ต SATA 6Gb / s
  • เมนบอร์ด: Gigabyte X99-SLI
  • หน่วยความจำ: 8 GiB

ข้อมูล ZFS

นี่คือลักษณะของ ZFS ก่อนที่จะเรียกใช้ fio นี่เป็นเพียงผลลัพธ์ของการสร้าง 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

ไม่มีรายละเอียดเหมือนฮาร์ดแวร์ที่ใช้ OS และเวอร์ชั่นตัวควบคุมการตั้งค่าระบบ ฯลฯ ฉันไม่แน่ใจว่าเราจะบอกอะไรคุณได้!
ewwhite

2
อะไรคือสิ่งที่ไดรฟ์ตัวเอง? เป็นไดรฟ์ SATA สำหรับผู้ใช้ทั่วไป คุณมีทางยาวที่จะพิสูจน์ว่าสามารถรองรับ 200+ MB / วินาทีได้อย่างยั่งยืน ไดรฟ์ SATA ระดับผู้บริโภคส่วนใหญ่ภายใต้เงื่อนไขในโลกแห่งความเป็นจริงจะโชคดีที่ได้รับการดำเนินงานมากกว่า 70-80 I / O ต่อวินาทีหรือมากกว่าประมาณ 100-120 MB / วินาที และถ้าคุณทำการสุ่มบล็อก I / O ขนาดเล็กลงในไดรฟ์นั้นคุณจะได้รับบางอย่างเช่น 30-40 KB / วินาที 10 GB ทั้งหมดนั้นง่ายเกินไปที่จะไขลานแคช
Andrew Henle

1
@ewwhite ไม่มีการตั้งค่าการปรับตั้งอยู่ใน/etc/modprobe.d/zfs.conf
สโนว์บอล

1
@ ขาวพวกเขาอยู่ ฉันเช็ดตารางพาร์ทิชันระหว่างการทดสอบแต่ละครั้ง ในทุกกรณีพาร์ติชันมีออฟเซ็ต 1 MiB จากจุดเริ่มต้นของดิสก์
สโนว์บอล

1
หมายเหตุถึงตัวเอง / คนอื่น ๆ ที่สะดุดในคำถามนี้: การตั้งค่าการปรับแต่งที่ ewwhite ระบุไว้มีการบันทึกman 5 zfs-module-parametersไว้
สโนว์บอล

คำตอบ:


6

ในขณะที่อายุฉันรู้สึกว่าคำถามนี้สมควรได้รับคำตอบ

fioปัญหาโดยค่าเริ่มต้น IOPs ขนาด 4KB; ชุดข้อมูล ZFS แทนใช้บันทึก 128KB โดยค่าเริ่มต้น ไม่ตรงกันนี้หมายความว่าการเขียน 4K แต่ละครั้งทำให้เกิดการอ่าน / แก้ไข / เขียนของระเบียน 128K ทั้งหมด

ในทางตรงกันข้าม ZVOL ใช้ volblocksize ขนาด 8K เป็นค่าเริ่มต้น ซึ่งหมายความว่าการเขียนแบบ 4K ทำให้เกิดวงจรการอ่าน / แก้ไข / เขียนที่เล็กกว่ามากของเร็กคอร์ด 8K และด้วยโชคบางอย่างการเขียนแบบ 4K สองอันสามารถรวมกันเป็นการเขียนแบบ 8K เดียว (ซึ่งไม่จำเป็นต้องอ่าน / แก้ไข / เขียนเลย)

ชุดระเบียน ZFS สามารถเปลี่ยนแปลงได้ด้วยzfs set recordize=8K <dataset>และในกรณีนี้ควรให้ประสิทธิภาพที่เทียบเท่ากับ ZVOL มากกว่าหรือน้อยกว่า แต่เมื่อนำมาใช้สำหรับการโอนเงินที่ค่อนข้างใหญ่ (OP พูดคุยเกี่ยวกับ 2 ไฟล์ MB ซึ่งเป็นภาพที่ควรจะอ่านทั้งหมดในแต่ละครั้งที่มีการเข้าถึงได้) มันจะดีกว่าที่จะมีขนาดใหญ่ recordsize / volblocksize การตั้งค่าเริ่มต้นแล้วบางครั้งแม้จะมีขนาดใหญ่ (128K)


4

หมายเหตุ: เนื่องจากงาน fio ขาดdirect=1( http://fio.readthedocs.io/en/latest/fio_doc.html#cmdoption-arg-direct ) I / O จำนวนหนึ่งที่กำลังดำเนินการ (ทั้งการอ่านและการเขียน) อาจถูกแคช โดยระบบปฏิบัติการบิดเบือนผลลัพธ์ของคุณ (และทำให้ตัวเลขสูงเกินจริง) สิ่งนี้เองมีความซับซ้อนมากขึ้นโดยต่อไปนี้:

  • ZFS บน Linux ไม่รองรับO_DIRECT(ดังนั้นการเปิดจึงล้มเหลว) หรือถ้าเป็นเช่นนั้นก็จะทำเช่นนั้นโดยถอยกลับไปที่บัฟเฟอร์ I / O อย่างเงียบ ๆ (ดูจุดที่ 3 ของhttps://github.com/zfsonlinux/zfs/commit / a584ef26053065f486d46a7335bea222cb03eeea )
  • ในบางกรณี BTRFS และ ext4 จะทำให้O_DIRECTถอยกลับไปเป็นบัฟเฟอร์ I / O

โปรดทราบว่าO_DIRECTการทำ I / O ที่ถูกบัฟเฟอร์ยังคงได้รับอนุญาตเพราะบน Linux O_DIRECTมีคำแนะนำมากกว่านี้ (ดูที่ส่วนการอ้างอิงของ/programming//a/46377629/2732969 )

หากคุณอยู่ในสถานการณ์ที่คุณไม่สามารถข้ามแคชได้อย่างถูกต้องเป็นสิ่งสำคัญที่คุณต้องทำ I / O ให้เพียงพอในพื้นที่ที่ใหญ่พอที่จะลดผลกระทบของการแคช (ยกเว้นแน่นอนคุณต้องการทดสอบการใช้แคช) ...

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.