ZFS neden ext4 ve btrfs'den daha yavaş?


11

Sorun

Son zamanlarda yeni bir disk taktım ve üzerinde bir zpool oluşturdum:

/# zpool create morez /dev/sdb

Bir süre kullandıktan sonra, oldukça yavaş olduğunu fark ettim:

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

Bu test gerçek kullanım durumuma oldukça benziyor. Diskten orta sayıda (~ 10k) görüntü (~ 2 MiB) okuyorum. Disk çoğunlukla boşken bir kerede yazıldılar, bu yüzden parçalanmalarını beklemiyorum.

Karşılaştırma için ext4'ü test ettim:

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

Ve 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 ile ilgili performans sorunlarına ne neden olabilir ve nasıl daha hızlı hale getirebilirim?

Bir çözüm başarısız oldu

Ayrıca diskim ( Seagate ST1000DM003 ) 4096 bayt fiziksel sektör kullandığından , açıkça zpool için sektör boyutunu ayarlamayı denedim :

/# zpool create -o ashift=12 morez /dev/sdb

Bu performansı iyileştirmedi:

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

Gözlem

Garip bir şekilde, bir zvol kullanmanın harika bir performansı vardı:

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

Bu neden zvols'u değil, yalnızca ZFS dosya sistemlerini etkiliyor?

Btrfs için genişletilmiş test

Yorumlarda, farkın önbelleğe almasından kaynaklanabileceği önerildi. Daha fazla testten sonra, durumun bu olduğuna inanmıyorum. Btrfs testinin boyutunu bilgisayarımın sahip olduğu bellek miktarının çok üstünde artırdım ve performansı hala ZFS'den daha büyüktü:

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

Sistem bilgisi

Yazılım

  • Arch Linux, çekirdek sürüm 4.11.6
  • Linux'ta ZFS 0.6.5.10
  • fio 2.21

Donanım

ZFS bilgisi

İşte fio çalıştırmadan önce ZFS özelliklerinin nasıl göründüğü. Bunlar sadece varsayılan ayarlarla bir zpool oluşturmanın sonucudur.

# 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

Kullanılan donanım, işletim sistemi ve sürüm, kontrolör, sistem ayarları gibi detaylar yok. Size ne söyleyebileceğimizden emin değilim!
ewwhite

2
Nedir sürücü kendisi? Hazır bir tüketici SATA diski. Aslında 200+ MB / sn'lik sürdürülebilir işleyebileceğini kanıtlamak için uzun bir yolunuz var. Gerçek dünya koşullarında çoğu tüketici sınıfı SATA sürücüsünün saniyede 70-80'den fazla I / O işlemi veya yaklaşık 100-120 MB / sn'den fazla işlem yapma şansı olacaktır. Ve böyle bir sürücüye rastgele küçük blok I / O işlemleri yaparsanız, muhtemelen 30-40 KB / sn gibi bir şey elde edersiniz . 10 GB önbellekte kolayca bitiyor olabilir.
Andrew Henle

1
@ewwhite Ayar ayarları mevcut değil/etc/modprobe.d/zfs.conf
Kartopu

1
@ewwhite Onlar. Her test arasındaki bölüm tablosunu sildim. Her durumda, disk diskin başlangıcından itibaren 1 MiB ofset değerine sahipti.
kartopu

1
Kendine / bu soruyla ilgili tökezleyen herkese dikkat edin: yeni bahsettiğimiz ayarlama ayarları belgelenir man 5 zfs-module-parameters.
Kartopu

Yanıtlar:


6

Yaşlandıkça bu sorunun bir cevabı hak ettiğini hissediyorum.

fiosorunlar, varsayılan olarak, 4KB boyutlu GİB'ler; ZFS veri kümeleri bunun yerine varsayılan olarak 128 KB kayıt kullanır. Bu uyumsuzluk, her 4K yazma işleminin tüm 128K kaydının bir okuma / değiştirme / yazma işlemine neden olduğu anlamına gelir.

Öte yandan, ZVOL'ler varsayılan olarak 8K volblockboyut kullanır. Bu, 4K yazma işleminin 8K kaydının çok daha küçük bir okuma / değiştirme / yazma döngüsüne neden olduğu ve bazı şanslarla iki 4K yazma işleminin tek bir 8K yazma işleminde birleştirilebileceği anlamına gelir ( hiç okuma / değiştirme / yazma gerektirmez ).

ZFS veri kümesi kayıt boyutu ile değiştirilebilir zfs set recordize=8K <dataset>ve bu durumda ZVOL'lerden daha fazla veya daha az eşdeğer performans vermelidir. Bununla birlikte, nispeten büyük transferler için kullanıldığında (OP, görüntüler olan her erişimde tamamen okunması gereken yaklaşık 2 MB dosyadan bahsetti) , bazen varsayılan ayardan (128K) daha büyük olan büyük kayıt boyutuna / volblock boyutuna sahip olmak daha iyidir .


4

Not: fio iş yoksun olarak direct=1( http://fio.readthedocs.io/en/latest/fio_doc.html#cmdoption-arg-direct ) I / O bir miktar (hem okur gerçekleştirildiği ve yazma) önbelleğe alınmış olabilir işletim sistemine göre, sonuçlarınızı bozarak (ve sayıları yapay olarak yüksek yaparak). Bu, aşağıdakilerle daha da karmaşıktır:

Farkında olun O_DIRECTLinux üzerinde çünkü hala I tamponlu yapıyor / Ç hala izin verilir O_DIRECTdaha bir ipucu olduğunu (ve referanslar bölümüne bakın https://stackoverflow.com/a/46377629/2732969 ).

Önbellekleri doğru bir şekilde atlayamayacağınız bir durumdaysanız, önbelleğin etkisini en aza indirmek için yeterince büyük bir alanda yeterli G / Ç yapmanız çok önemlidir (elbette önbelleği test etmek istemiyorsanız) ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.