Problème
J'ai récemment installé un nouveau disque et créé un zpool dessus:
/# zpool create morez /dev/sdb
Après l'avoir utilisé pendant un certain temps, j'ai remarqué que c'était assez lent:
/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)
Ce test est assez similaire à mon cas d'utilisation réel. Je lis un nombre modéré (~ 10k) d'images (~ 2 MiB chacune) à partir du disque. Ils ont été écrits d'un coup alors que le disque était presque vide, donc je ne m'attends pas à ce qu'ils soient fragmentés.
Pour comparaison, j'ai testé 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)
Et 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)
Qu'est-ce qui pourrait être à l'origine des problèmes de performances avec ZFS et comment puis-je le rendre plus rapide?
Échec d'une tentative de solution
J'ai également essayé de définir explicitement la taille du secteur pour le zpool, car mon disque ( Seagate ST1000DM003 ) utilise des secteurs physiques de 4096 octets:
/# zpool create -o ashift=12 morez /dev/sdb
Cela n'a pas amélioré les performances:
/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)
Observation
Curieusement, l'utilisation d'un zvol a eu de grandes performances:
/# 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)
Pourquoi cela n'affecte-t-il que les systèmes de fichiers ZFS et non les zvols?
Tests étendus pour btrfs
Dans les commentaires, il a été suggéré que la différence pourrait être due à la mise en cache. Après de nouveaux tests, je ne pense pas que ce soit le cas. J'ai augmenté la taille du test btrfs bien au-dessus de la quantité de mémoire de mon ordinateur et ses performances étaient encore nettement supérieures à celles de 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)
Information système
Logiciel
- Arch Linux, version du noyau 4.11.6
- ZFS sur Linux 0.6.5.10
- fio 2.21
Matériel
- Disque en cours de test: Seagate ST1000DM003 , connecté au port SATA 6 Gb / s
- Carte mère: Gigabyte X99-SLI
- Mémoire: 8 Gio
Informations ZFS
Voici à quoi ressemblaient les propriétés ZFS avant d'exécuter fio. Ce ne sont que le résultat de la création d'un zpool avec les paramètres par défaut.
# 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
la source
/etc/modprobe.d/zfs.conf
man 5 zfs-module-parameters
.Réponses:
Bien que vieille, je pense que cette question mérite une réponse.
fio
émet, par défaut, des IOP de 4 Ko; Les jeux de données ZFS, à la place, utilisent 128 Ko d'enregistrement par défaut. Cette incompatibilité signifie que chaque écriture 4K entraîne une lecture / modification / écriture de l'ensemble de l'enregistrement 128K.Les ZVOL, d'autre part, utilisent la taille de bloc vol 8K par défaut. Cela signifie qu'une écriture 4K entraîne un cycle de lecture / modification / écriture beaucoup plus petit d'un enregistrement 8K et, avec un peu de chance, deux écritures 4K peuvent être fusionnées en une seule écriture 8K (qui ne nécessite aucune lecture / modification / écriture).
La taille d'enregistrement du jeu de données ZFS peut être modifiée avec
zfs set recordize=8K <dataset>
et, dans ce cas, elle devrait donner des performances plus ou moins équivalentes à celles des ZVOL. Cependant, lorsqu'il est utilisé pour des transferts relativement importants (OP parlait de fichiers de 2 Mo qui, étant des images, devraient être entièrement lus chaque fois qu'ils sont accédés), il est préférable d'avoir une taille d' enregistrement / volblocs volumineuse, parfois encore plus grande que le paramètre par défaut (128K).la source
Remarque: comme le travail fio manque
direct=1
( http://fio.readthedocs.io/en/latest/fio_doc.html#cmdoption-arg-direct ), une partie des E / S en cours d'exécution (en lecture et en écriture) peut être mise en cache par le système d'exploitation, faussant vos résultats (et rendant les chiffres artificiellement élevés). Cela est encore plus compliqué par les éléments suivants:O_DIRECT
(donc l'ouverture échoue) ou si c'est le cas, il le fait en retombant discrètement sur les E / S tamponnées (voir le point 3 de https://github.com/zfsonlinux/zfs/commit / a584ef26053065f486d46a7335bea222cb03eeea ).O_DIRECT
revenir aux E / S tamponnées.Soyez conscient
O_DIRECT
que les E / S tamponnées sont toujours autorisées car sous Linux,O_DIRECT
c'est plus un indice (voir la section références de /programming//a/46377629/2732969 ).Si vous êtes dans une situation où vous ne pouvez pas contourner correctement les caches, il est crucial que vous fassiez suffisamment d'E / S sur une zone suffisamment grande pour minimiser l'impact de la mise en cache (à moins, bien sûr, que vous souhaitiez réellement tester la mise en cache) ...
la source