Article d’origine : « ZFS Administration, Part I- VDEVs » publié le 04/12/2012. Licence : CC BY-NC-SA 3.0 US.
Ceci est le premier billet d’une longue série sur comment administrer vos système de fichiers et pools ZFS (zpool). Vous devriez commencer par lire comment installer ZFS sur votre système GNU/Linux pour revenir ensuite à ce billet.
Introduction aux périphériques virtuels
Pour commencer, il faut comprendre le concept des périphériques virtuels (ou VDEV) du fait que ZFS les utilise considérablement en interne. Si vous êtes déjà familier avec RAID, alors ce concept n’est pas nouveau pour vous bien que vous ne vous y référiez pas forcément en tant que « VDEV ». En gros, c’est un meta-périphérique qui représente un ou plusieurs périphériques physiques. Avec du RAID logiciel sous Linux, vous pourriez avoir un périphérique « /dev/md0 » qui représente une grappe RAID-5 de quatre disques. Dans ce cas, « /dev/md0 » serait votre « VDEV ».
Il y a sept types de VDEV dans ZFS :
- disk (par défaut) — les disques physiques de votre système ;
- file — un chemin absolu vers des fichiers/images pré-alloués ;
- mirror — miroir RAID-1 logiciel standard ;
- raidz1/2/3 — niveaux de RAID logiciel non standards à base de parité distribuée ;
- spare — disques durs marqués comme « remplacement à chaud » (hot spare) pour le RAID logiciel ZFS ;
- cache — périphérique utilisé pour un cache de lecture adaptatif de niveau deux (L2ARC) ;
- log — un journal séparé (SLOG) appelé « ZFS Intent Log » ou ZIL.
Il est important de noter que les VDEV sont toujours entrelacés (striped) dynamiquement. Tout cela aura plus de sens au fur et à mesure des commandes présentées ci-dessous. Cela dit, supposons que nous ayons quatre disques dans un entrelacement ZFS. La taille de l’entrelacement est calculée par le nombre de disques et la taille des disques dans la grappe. Si d’autres disques sont ajoutés, la taille de l’entrelacement peut être ajustée au besoin pour le disque additionnel, d’où la nature dynamique de l’entrelacement.
Quelques avertissements au niveau d’un zpool
Je me sentirais un peu mal de ne pas mentionner ces mises en garde à propos de ZFS :
- Une fois qu’un périphérique est ajouté à un VDEV, il ne peut plus être enlevé ;
- Vous ne pouvez pas réduire un zpool, seulement l’agrandir ;
- RAID-0 est plus rapide que RAID-1, qui est plus rapide que RAIDZ-1, qui est plus rapide que RAIDZ-2, qui est plus rapide que RAIDZ-3 ;
- Les disques de remplacement (hot spare) ne sont pas ajoutés dynamiquement à moins d’activer l’option qui est désactivée par défaut ;
- Un zpool ne se redimensionnera pas dynamiquement lorsque des disque de plus grande capacité sont ajoutés à moins d’activer l’option avant de remplacer le premier disque. Option qui est aussi désactivée par défaut ;
- Un zpool saura profiter du « format avancé » des secteurs 4K des disques si et seulement si le disque le signale ;
- La déduplication est extrêmement onéreuse et causera des dégradations de performance s’il n’y a pas assez de RAM installée. Elle s’applique à tout un pool et n’est pas locale aux systèmes de fichiers ;
- D’un autre côté, la compression est extrêmement bon marché d’un point de vue processeur, pourtant elle est désactivée par défaut ;
- ZFS souffre grandement de la fragmentation et des zpools pleins « ressentiront » la dégradation de performance ;
- ZFS supporte le chiffrement nativement mais ce n’est pas du Logiciel Libre. Le chiffrement est propriétaire sous copyright d’Oracle.
Pour les exemples suivants, nous partons du principe que nous avons quatre disques : /dev/sde, /dev/sdf, /dev/sdg et /dev/sdh qui sont tous des clés USB de 8 Go. Entre chacune des commandes, si vous les suivez, soyez sûr d’appliquer l’étape de nettoyage entre chaque section.
Un simple pool
Commençons par créer un simple zpool avec les quatre disques. Je peux créer un zpool nommé « tank » avec la commande suivante :
# zpool create tank sde sdf sdg sdh
Ici j’utilise quatre VDEV disk. Notez que je n’utilise pas les chemins complets vers les périphériques bien que je le pourrais. Étant donné que les VDEV sont toujours entrelacés dynamiquement, c’est effectivement un RAID-0 entre quatre disques (sans redondance). Nous devrions aussi vérifier l’état du zpool :
# zpool status tank
pool: tank
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
sdg ONLINE 0 0 0
sdh ONLINE 0 0 0
errors: No known data errors
Supprimons le zpool et créons-en un nouveau. Lancez cette commande avant de continuer si vous suivez les instructions dans votre propre terminal :
# zpool destroy tank
Un simple miroir zpool
Dans l’exemple suivant, je souhaite faire un miroir avec les quatre disques (/dev/sde, /dev/sdf, /dev/sdg et /dev/sdh). Aussi, plutôt que d’utiliser le VDEV disk, j’utiliserai « mirror ». La commande est la suivante :
# zpool create tank mirror sde sdf sdg sdh
# zpool status tank
pool: tank
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
sdg ONLINE 0 0 0
sdh ONLINE 0 0 0
errors: No known data errors
Notez que « mirror-0 » est dorénavant le VDEV et qu’il supervise chaque périphérique physique. Comme mentionné plus tôt, ceci est analogue au périphérique « /dev/md0 » en RAID logiciel sous Linux et représentant les quatre périphériques physiques. Nettoyons notre zpool et créons-en un autre.
# zpool destroy tank
VDEV imbriqués
Les VDEV peuvent être imbriqués. Un parfait exemple est un RAID-1+0 standard (communément appelé « RAID-10 »). C’est un entrelacement de miroirs. Afin de spécifier les VDEV imbriqués, je les mets simplement sur la ligne de commande dans l’ordre (l’emphase est de mon fait) :
# zpool create tank mirror sde sdf mirror sdg sdh
# zpool status
pool: tank
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
sdg ONLINE 0 0 0
sdh ONLINE 0 0 0
errors: No known data errors
Le premier VDEV est « mirror-0 » et il gère /dev/sde ainsi que /dev/sdf. Cela a été fait en appelant « mirror sde sdf ». Le second VDEV est « mirror-1 » et il gère /dev/sdg ainsi que /dev/sdh. Cela a été fait en appelant « mirror sdg sdh ». Comme les VDEV sont toujours entrelacés dynamiquement, « mirror-0 » et « mirror-1 » sont entrelacés, d’où la création d’une configuration RAID-1+0. N’oubliez pas de nettoyer avant de continuer :
# zpool destroy tank
VDEV fichiers
Comme mentionné, des fichiers pré-alloués peuvent être utilisés pour configurer des zpools sur votre système de fichiers ext4 (ou autre). Il est à noter que cela est uniquement destiné à des fins de tests et non pas pour stocker des données de production. Utiliser des fichiers est une très bonne façon d’avoir un bac à sable où vous pouvez tester des ratios de compression, la taille de la table de déduplication ou d’autres choses sans réellement engager des données de production. Quand on crée des VDEV file, on ne peut pas utiliser de chemins relatifs et on doit utiliser des chemins absolus. De plus, les fichiers images doivent être préalloués et non pas partiellement alloués ou avoir une allocation fine et dynamique. Voyons comment ça marche :
# for i in {1..4}; do dd if=/dev/zero of=/tmp/file$i bs=1G count=4 &> /dev/null; done
# zpool create tank /tmp/file1 /tmp/file2 /tmp/file3 /tmp/file4
# zpool status tank
pool: tank
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
/tmp/file1 ONLINE 0 0 0
/tmp/file2 ONLINE 0 0 0
/tmp/file3 ONLINE 0 0 0
/tmp/file4 ONLINE 0 0 0
errors: No known data errors
Ici nous avons créé un RAID-0. Nous avons utilisé des fichiers pré-alloués en utilisant /dev/zero et faisant une taille de 4 Go chacun. De ce fait la taille de notre zpool a un espace utilisable de 16 Go. Chaque fichier, tout comme notre premier exemple utilisant des disques, est un VDEV. Bien sûr, vous pouvez traiter les fichiers comme des disques et les mettre dans une configuration de type miroir, RAID-1+0, RAIDZ-1 (voir ci-dessous), etc.
# zpool destroy tank
Pools hybrides
Ce dernier exemple devrait vous montrer les pools complexes que vous pouvez configurer en utilisant différents VDEV. En utilisant nos quatre VDEV file de l’exemple précédent et nos quatre VDEV disk (/dev/sde jusqu’à /dev/sdh), créons un pool hybride avec des disques pour un cache et un journal. Encore une fois, j’ai mis en gras les VDEV imbriqués pour plus de clarté :
# zpool create tank mirror /tmp/file1 /tmp/file2 mirror /tmp/file3 /tmp/file4 log mirror sde sdf cache sdg sdh
# zpool status tank
pool: tank
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
/tmp/file1 ONLINE 0 0 0
/tmp/file2 ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
/tmp/file3 ONLINE 0 0 0
/tmp/file4 ONLINE 0 0 0
logs
mirror-2 ONLINE 0 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
cache
sdg ONLINE 0 0 0
sdh ONLINE 0 0 0
errors: No known data errors
Il se passe beaucoup de choses ici, décortiquons tout ça. Premièrement, nous créons un RAID-1+0 en utilisant nos quatre fichiers images préalloués. Remarquez les VDEV « mirror-0 » et « mirror-1 » et ce qu’ils gèrent. Deuxièmement, nous créons un troisième VDEV nommé « mirror-2 » qui n’est en fait pas utilisé pour stocker des données dans le pool mais qui est utilisé comme ZFS Intent Log ou ZIL. Nous verrons le ZIL plus en détail dans un autre billet. Ensuite nous créons deux VDEV pour cacher les données nommés « sdg » et « sdh ». Ce sont des VDEV disk standards que nous avons déjà vus. Cependant, ils sont aussi gérés par le VDEV de « cache ». Ici nous avons donc utilisé six des septs VDEV listés plus haut, le seul manquant est le « spare ».
Prendre en compte l’indentation vous aidera à voir quel VDEV gère quoi. Le pool « tank » est composé des VDEV « mirror-0 » et « mirror-1 » pour du stockage persistant à long terme. Le ZIL est géré par « mirror-2 » qui est composé de /dev/sde et /dev/sdf. Le VDEV de cache en lecture seule est géré par deux disques, /dev/sdg et /dev/sdh. Ni les « logs » ni le « cache » ne sont du stockage à long terme pour le pool, d’où la création d’une configuration de type « pool hybride ».
# zpool destroy tank
Un exemple de la vraie vie
En production, les fichiers seraient des disques physiques et le ZIL ainsi que le cache seraient de rapides SSD. Voilà ma configuration zpool actuelle qui stocke ce blog (NdT : celui de l’auteur de l’article d’origine), entre autres choses :
# zpool status pool
pool: pool
state: ONLINE
scan: scrub repaired 0 in 2h23m with 0 errors on Sun Dec 2 02:23:44 2012
config:
NAME STATE READ WRITE CKSUM
pool ONLINE 0 0 0
raidz1-0 ONLINE 0 0 0
sdd ONLINE 0 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
sdg ONLINE 0 0 0
logs
mirror-1 ONLINE 0 0 0
ata-OCZ-REVODRIVE_OCZ-33W9WE11E9X73Y41-part1 ONLINE 0 0 0
ata-OCZ-REVODRIVE_OCZ-X5RG0EIY7MN7676K-part1 ONLINE 0 0 0
cache
ata-OCZ-REVODRIVE_OCZ-33W9WE11E9X73Y41-part2 ONLINE 0 0 0
ata-OCZ-REVODRIVE_OCZ-X5RG0EIY7MN7676K-part2 ONLINE 0 0 0
errors: No known data errors
Remarquez que mes VDEV « logs » et « cache » sont des SSD OCZ Revodrive tandis que les quatre disques à plateaux sont dans un VDEV RAIDZ-1 (nous traiterons de RAIDZ dans le prochain billet). Quoi qu’il en soit, il faut remarquer que le nom des SSD est « ata-OCZ-REVODRIVE_OCZ-33W9WE11E9X73Y41-part1 », etc. Ils se trouvent dans /dev/disk/by-id/. La raison pour laquelle je les ai choisis à la place de « sdb » et « sdc » est que les périphériques de cache et de log ne stockent pas nécessairement les mêmes métadonnées ZFS. Ainsi, quand le pool est créé au démarrage, il se peut qu’ils ne soient pas intégrés dedans et qu’ils soient manquants. Ou la carte mère peut assigner les lettres des lecteurs dans un ordre différent. Cela n’est pas un problème avec le pool principal mais c’en est un gros sous GNU/Linux avec des périphériques de cache et de logs. En utilisant le nom du périphérique sous /dev/disk/by-id/, cela assure une plus grande persistence et unicité.
On peut remarquer aussi la simplicité de l’implémentation. Pour faire quelque chose de similaire avec LVM, RAID et ext4, il faudrait faire ce qui suit :
# mdadm -C /dev/md0 -l 0 -n 4 /dev/sde /dev/sdf /dev/sdg /dev/sdh
# pvcreate /dev/md0
# vgcreate /dev/md0 tank
# lvcreate -l 100%FREE -n videos tank
# mkfs.ext4 /dev/tank/videos
# mkdir -p /tank/videos
# mount -t ext4 /dev/tank/videos /tank/videos
Ce qui est fait ci-dessus a été fait avec ZFS en une seule commande (moins la création du volume logique, que nous verrons plus tard) au lieu de sept.
Conclusion
Ce billet devrait être un bon point de départ pour avoir une compréhension de base des zpool et VDEV. Tout le reste en découlera. Vous avez maintenant franchi le plus gros obstacle qui est de comprendre comment ZFS gère le stockage groupé. Nous devons encore voir les niveaux RAIDZ et nous devons approfondir les périphériques de cache et de log ainsi que les options de pool tels que la déduplication et la compression. Mais nous verrons tout cela dans d’autres billets. Ensuite nous pourrons nous intéresser aux jeux de données du système de fichiers ZFS, leurs options, leurs avantages et leurs défauts. Mais vous avez maintenant une longueur d’avance sur la partie essentielle des pools ZFS.