ZFS : Le FileSystem par excellence

From Deimos.fr / Bloc Notes Informatique
Jump to: navigation, search
ZFS

1 Introduction

ZFS pour Z File System, est un système de fichier open source sous licence CDDL. Le 'Z' ne signifie rien de particulier officiellement mais est connu dans la presse sous différents noms tel Zettabyte de l'unité anglaise zettabyte (zettaoctet en français) concernant le stockage de données informatiques, mais aussi ZFS pour le dernier mot dans les systèmes de fichiers (the last word in filesystems)[1].

Produit par Sun Microsystems pour Solaris 10 et supérieur, il a été conçu par l'équipe de Jeff Bonwick. Annoncé pour septembre 2004, il a été intégré à Solaris le 31 octobre 2005 et le 16 novembre 2005 en tant que feature du build 27 d'OpenSolaris. Sun a annoncé que ZFS était intégré dans la mise à jour de Solaris datée de juin 2006, soit un an après l'ouverture de la communauté OpenSolaris.

Les caractéristiques de ce système de fichier sont sa très haute capacité de stockage, l'intégration de tous les concepts précédents concernant les systèmes de fichiers et la gestion de volume en un seul produit. Il intègre la structure On-Disk, il est léger et permet facilement la mise en place d'une plate-forme de gestion de stockage.

2 Localiser ses disques

Utilisez vos outils habituels pour connaitre vos disques. Par exemple sous Solaris :

Command format
bash-3.00# format 
Searching for disks...done
 
 
AVAILABLE DISK SELECTIONS:
       0. c0t600A0B80005A2CAA000004104947F51Ed0 <SUN-LCSM100_F-0670-10.00GB>
          /scsi_vhci/disk@g600a0b80005a2caa000004104947f51e
       1. c0t600A0B80005A2CB20000040B4947F57Fd0 <DEFAULT cyl 1303 alt 2 hd 255 sec 63>
          /scsi_vhci/disk@g600a0b80005a2cb20000040b4947f57f
       2. c1t1d0 <DEFAULT cyl 5098 alt 2 hd 255 sec 63>
          /pci@0,0/pci8086,25e2@2/pci8086,3500@0/pci8086,3510@0/pci1000,3150@0/sd@1,0
       3. c2t1d31 <DEFAULT cyl 17 alt 2 hd 64 sec 32>
          /pci@0,0/pci8086,25f8@4/pci1077,143@0/fp@0,0/disk@w203400a0b85a2caa,1f
       4. c3t3d31 <DEFAULT cyl 17 alt 2 hd 64 sec 32>
          /pci@0,0/pci8086,25f8@4/pci1077,143@0,1/fp@0,0/disk@w203500a0b85a2caa,1f

3 Zpool

Un Zpool c'est comme un VG (Volume Group) pour ceux qui ont fait du LVM. Le problème c'est qu'a l'heure ou j'écris l'article, on ne peut réduire la taille d'un zpool, parcontre on peut l'agrandir. On peut utiliser directement un zpool en tant que Filesystem car de base il est en ZFS. Cependant, on peut créer des filesystems ZFS (ça s'appelle comme ça, je sais c'est con, mais voyez plutôt ça comme un LV (Logical Volume) ou partition). On peut également créer d'autres filesystems contenant d'autres types de filesystem (NTFS, EXT4, REIZERFS...).

3.1 Création d'un zpool

Pour créer un zpool, voici la démarche a suivre :

Command zpool
zpool create zpool_name c0t600A0B80005A2CAA000004104947F51Ed0

  • zpool_name : mettez le nom qui vous intéresse pour le zpool
  • c0t600A0B80005A2CAA000004104947F51Ed0 : c'est le nom du device affiché par la commande format

3.2 Lister les zpool

3.2.1 Simple Zpool

Pour connaitre quels sont les pools existants sur la machine :

Command zpool
zpool list

3.2.2 Raid-Z

Un Raid-Z est comme un Raid 5, mais avec un gros problèmes en moins : pas de resyncro des parités ou de pertes lors d'une coupure de courant. Voici comment faire :

Command zpool
zpool create my_raidz raidz c1t0d0 c2t0d0 c3t0d0 c4t0d0 /dev/dsk/c5t0d0

3.3 Monter un zpool

Par défaut, les zpool ont comme point de montage /zpool_name. Pour monter un zpool, nous allons utiliser la commande zfs :

Command zfs
zfs mount zpool_name

Il va se rappeller ou il doit se monter, car ce genre d'informations est stocké dans le filesystem.

3.4 Démonter un zpool

Là, c'est super simple, comme d'habitude j'ai envie de dire :

Command umount
umount /zpool_name

Il suffit de faire umount suivit du point e montage

3.5 Suppression d'un zpool

Pour supprimer un zpool :

Command zpool
zpool destroy zpool_name

3.6 Agrandir un zpool

Pour agrandir un zpool, nous utiliserons lenom du zpool, ainsi que le device supplémentaire :

Command zpool
zpool add zpool_name device1 device2...

3.7 Modifier les paramètres du zpool

3.7.1 Modifier le point de montage d'un zpool

Par défaut, les zpool se montent dans /, pour changer ceci :

Command zfs
zfs set mountpoint=/mnt/datas my_zpool

  • /mnt/datas : le point de montage souhaité
  • my_zpool : nom du zpool

3.8 Importer tous les zpool

Pour importer tous les zpools :

Command zpool
zpool import -f -a

  • -f : forcer (facultatif et peut être dangereux dans certains cas)
  • -a : va importer tous les zpools

3.9 Renommer un zpool

Renommer un zpool n'est en fait pas très compliquer :

Command zpool
zpool export mon_zpool
zpool import mon_zpool mon_nouveau_nom_de_zpool

Et voilà, le zpool est renommer :-).

3.10 Utilisation dans un environnement cluster

En environnement cluster, vous aurez besoin de monter et démonter des zpools assez régulièrement. Si vous utiliser Sun Cluster (à l'heure ou j'écris ceci en version 3.2), on est obliger d'utiliser les zpool pour les montages des partitions. Les filesystems ne peuvent etre montés et démontés d'un noeud a l'autre lorsqu'ils appartiennent au même zpool.

Il va donc falloir démonter le zpool, exporter les infos dans le ZFS, puis l'importer sur l'autre noeud. Imaginons le scénario suivant :

  • sun-node1 (noeud 1)
  • sun-node2 (noeud 2)
  • 1 baie de disque avec 1 LUN de 10 Go

Le LUN est un zpool créer comme décrit plus haut dans cette doc sur sun-node1. Il va donc maintenant falloir basculer ce zpool sur sun-node2. Sachant que ZFS n'est pas un filesystem cluster, nous devons le démonter, exporter les infos, puis l'importer. Le démontage n'est pas obligatoire puisque c'est l'export qui va le faire, mais si on souhaites faire les choses proprement, alors allons y sur sun-node1 :

Command
umount /zpool_name
export zpool_name

Maintenant, listez les zpools disponible, on ne devrait plus le voir. Passons sur sun-node2

Command zpool
zpool import zpool_name

Voilà, vous retrouvez vos fichiers, normalement c'est automatiquement monté, mais si des fois ça n'était pas le cas vous pouvez le faire à la main (voir plus haut).

4 ZFS

4.1 Créer une partition ZFS

Pour créer une partition ZFS, c'est extrêmement simple ! Vous avez évidemment votre Zpool qui est créer, puis vous exécutez :

Command zfs
zfs create zpool/partition

Ensuite vous pouvez spécifier des options avec -o et voir toutes les options disponibles avec un :

Command zfs
zfs get all zpool/partition

4.2 Renommer une partition

Pour renommer une partition ZFS. Si vous souhaitez renommer une partition ZFS, rien de plus simple :

Command zfs
zfs rename zpool/partitionold zpool/partitionnew

5 Gestion de la Swap sur ZFS

Sur solaris, on peut se servir de plusieurs espace de swap combinés (Partitions + fichier indiferement).

pour lister les espace de swap utilisés :

Command swap
> swap -l
swapfile                  dev     swaplo blocks   free
/dev/zvol/dsk/rpool/swap1 181,3       8  4194296  4194296
/dev/zvol/dsk/rpool/swap  181,2       8  62914552 62914552

pour en savoir un peu plus on peut également utiliser :

Command swap
> swap -s
total: 283264k bytes allocated + 258412k reserved = 541676k used, 31076108k available

Ici nous avons deux volumes ZFS qui servent de swap. par defaut lors de la création d'un ZPOOL, un espace de swap est créé "rpool/swap".

5.1 Ajouter de la SWAP

Il suffit d'agrandir la taille du ZFS associé a la swap.

5.1.1 Ajouter une swap

Verifions le nombre de swap attribuées :

Command swap
> swap -l
swapfile             dev  swaplo blocks   free
/dev/dsk/c1t0d0s1   30,65      8 8401984 8401984

Maintenant on ajoute un ZFS :

Command swap
zfs create -V 30G rpool/swap1

Ici nous venons de créer la swap a 30G. Puis nous déclarons cette nouvelle partition comme swap :

Command swap
swap -a /dev/zvol/dsk/rpool/swap1

Maintenant, lorsque j'affiche la liste des partitions actives, je peux voir la nouvelle :

Command swap
 > swap -l
swapfile             dev  swaplo blocks   free
/dev/dsk/c1t0d0s1   30,65      8 8401984 8401984
/dev/dsk/c1t0d0s5   30,69      8 146801960 146801960

Si vous avez ce genre de message :

/dev/zvol/dsk/rpool/swap is in use for live upgrade -. Please see ludelete(1M).

Il faudra utiliser la commande suivante pour l'activer :

Command swapadd
/sbin/swapadd

5.1.2 Agrandir une swap

Lorsque la machine tourne et que l'espace de swap est utilisé, on peut agrandir la taille de la swap pour que le système puisse s'en servir. Cela nécessitera une désactivation puis réactivation pour que le nouvel espace soit prise en compte. Pour cela nous allons agrandir le zfs :

Command zfs
zfs set volsize=72G rpool/swap
zfs set refreservation=72G rpool/swap

Nous allons maintenant désactiver la swap :

Command zfs
swap -d /dev/zvol/dsk/rpool/swap

Il faut maintenant supprimer ou commenter l'entrée dans /etc/vfstab qui correspond à la swap, car elle sera automatiquement créer dans l'étape suivante :

Configuration File /etc/vfstab
#/dev/zvol/dsk/rpool/swap    -   -   swap    -   no  -

puis la réactiver pour que la nouvelle taille soit prise en compte :

Command swap
 swap -a /dev/zvol/dsk/rpool/swap

On peut vérifier la taille du swap :

Configuration File swap
> swap -l
swapfile             dev  swaplo blocs   libres
/dev/zvol/dsk/rpool/swap 181,1       8 150994936 150994936

6 Utilisation avancée

6.1 Le cache ARC ZFS

Le problème de ZFS est qu'il est très gourmand en RAM (environ 1/8 de la total + swap). Ce qui peut s'avérer vite gênant sur des machines ayant beaucoup de RAM. voici donc un peu d'explication.

6.1.1 Mémoire disponible mdb -k et le cache I/O ZFS ARC

La commande mdb -k avec l'option ::memstat permet d'avoir une vision globale de la mémoire disponible sur une machine Solaris

Command echo
echo ::memstat | mdb -k
 
Page Summary                Pages                MB  %Tot
------------     ----------------  ----------------  ----
Kernel                     587481              2294    7%
Anon                       180366               704    2%
Exec and libs                6684                26    0%
Page cache                   7006                27    0%
Free (cachelist)            13192                51    0%
Free (freelist)           7591653             29654   91%
 
Total                     8386382             32759
Physical                  8177488             31943

Dans l'exemple ci-dessus, il s'agit d'une machine disposant de 32 Gb de mémoire physique.

ZFS utilise un cache noyau (cache kernel) appelé ARC pour les I/Os. Pour connaître la taille du cache I/O à un instant t utilisée par ZFS, utiliser l'option kmastat avec la commande mdb -k et repérer la statistique Total [zio_buf] :

Command echo
echo ::kmastat | mdb -k
 
cache                        buf    buf    buf    memory     alloc alloc 
name                        size in use  total    in use   succeed  fail 
------------------------- ------ ------ ------ --------- --------- ----- 
 ...
Total [zio_buf]                                1157632000   1000937     0
 ...

Dans l'exemple ci-dessus, le cache I/O ZFS utilise 1,1 G en mémoire

6.1.2 Limitation du cache ARC zfs (zfs_arc_max et zfs_arc_min)

Pour les machines disposant d'une quantité de mémoire très importante, il est préférable de limiter le cache I/O ZFS pour éviter tout débordement de mémoire sur les autres applications. Dans la pratique ce cache augmente et diminue dynamiquement en fonction des besoins des applications installées sur la machine, mais il est préférable de le limiter pour prévenir tout risque. Le paramètre zfs_arc_max (en bytes) dans le fichier /etc/system permet de limiter la quantité de mémoire au cache I/O ZFS. Ci-dessous un exemple ou le cache I/O ZFS est limité à 4Gb :

Configuration File /etc/system
...
set zfs:zfs_arc_max = 4294967296
...

6.1.3 Statistiques sur le cache ARC ZFS (kstat zfs)

De même il est possible de spécifier la quantité de mémoire minimale à allouer au cache I/O ZFS avec le paramètre zfs_arc_min dans le fichier /etc/system.

La commande kstat avec l'option zfs donne des statistiques détaillées sur le cache ZFS ARC (hits, misses, taille etc...) à un instant t : on retrouve la valeur maximale possible (c_max) pour ce cache, la taille courante (size) dans la sortie de cette commande. Dans l'exemple ci-dessous, le paramètre zfs_arc_max n'a pas encore été appliqué, ce qui explique que la taille maximale possible correspond à la mémoire physique de la machine.

Command kstat
> kstat zfs
module:zfs                             instance: 0     
name:  arcstats                        class:    misc
       c                               33276878848
       c_max                           33276878848
       c_min                           4159609856
       crtime                          121.419237623
       deleted                         497690
       demand_data_hits                14319099
       demand_data_misses              6491
       demand_metadata_hits            45356553
       demand_metadata_misses          33470
       evict_skip                      2004
       hash_chain_max                  4
       hash_chains                     1447
       hash_collisions                 1807933
       hash_elements                   40267
       hash_elements_max               41535
       hdr_size                        6992496
       hits                            60821130
       l2_abort_lowmem                 0
       l2_cksum_bad                    0
       l2_evict_lock_retry             0
       l2_evict_reading                0
       l2_evict_reading                0
       l2_feeds                        0
       l2_free_on_write                0
       l2_hdr_size                     0
       l2_hits                         0
       l2_io_error                     0
       l2_misses                       0
       l2_rw_clash                     0
       l2_size                         0
       l2_writes_done                  0
       l2_writes_error                 0
       l2_writes_hdr_miss              0
       l2_writes_sent                  0
       memory_throttle_count           0
       mfu_ghost_hits                  3387
       mfu_hits                        53995731
       misses                          48704
       mru_ghost_hits                  1180
       mru_hits                        5891117
       mutex_miss                      0
       p                               21221559296
       prefetch_data_hits              237031
       prefetch_data_misses            3520
       prefetch_metadata_hits          908447
       prefetch_metadata_misses        5223
       recycle_miss                    0
       size                            1362924368
       snaptime                        14013729.1668961

module:zfs                             instance: 0     
name:  vdev_cache_stats                class:    misc
       crtime                          121.419271852
       delegations                     4453
       hits                            27353
       misses                          9753
       snaptime                        14013729.1677954

Je vous conseille également le très bon arc_summary qui permet d'obtenir des informations très précise ou encore arcstat.

6.2 Ne pas monter tous les Zpool au boot

Si vous rencontrez des erreurs au boot de votre machine, lors du montage des Zpool (pour mon cas, un reboot en continue de la machine), il y a une solution qui permet de lui faire oublier tous ceux qui étaient importés durant la dernière session (ZFS se rappel des zpool importés et les réimporte automatiquement lors d'un boot, ce qui est pratique mais peut être contraignant dans certains cas).

Pour ce faire, il va falloir booter en mode single user ou multi user (si ça ne fonctionne pas, essayer le mode failsafe pour Solaris (chrooté pour Linux)), puis nous allons enlever le cache ZFS :

Command mv
mv /etc/zfs/zpool.cache /etc/zfs/zpool.cache.`date "+%Y-%m-%d"`

Si votre OS est installé sur du ZFS, que vous êtes en mode failsafe, il va falloir repopuler le cache (le /a correspond sous Solaris au root) :

Command
cd /
bootadm update-archive -R /a
umount /a

Ensuite on reboot et on réimporte les Zpool souhaités.

7 FAQ

7.1 FAULTED

Je me suis tapé un petit FAULTED comme on peut le voir plus bas sans trop savoir pourquoi :

Command zpool
bash-3.00# zpool list
NAME             SIZE   USED  AVAIL    CAP  HEALTH  ALTROOT
test1      -      -      -      -  FAULTED  -

Et là il faut un peu débugger. Pour ça on utilise la commande suivante :

Command zpool
bash-3.00# zpool status -x
  pool: test1
 state: UNAVAIL
status: One or more devices could not be opened.  There are insufficient
        replicas for the pool to continue functioning.
action: Attach the missing device and online it using 'zpool online'.
   see: http://www.sun.com/msg/ZFS-8000-3C
 scrub: none requested
config:

        NAME                                     STATE     READ WRITE CKSUM
                test1                           UNAVAIL      0     0     0  insufficient replicas
         c4t600A0B800048A9B6000005B84A8293C9d0  UNAVAIL      0     0     0  cannot open

Là c'est pas forcément bon signe hein ! Les messages d'erreur font flipper. Pourtant la solution est simple, il s'uffit d'exporte puis de réimporter (en forçant si nécessaire) les zpools défectueux.

Ensuite, on peut vérifier l'état de son filesystem via un scrub :

Command zpool
zpool scrub test1
zpool status

7.2 How to repair grub after zpool upgrade

It appears that zpool upgrade can break grub bootloader.

To fix this, we need to reinstall grub on the partition. proceed as follow :

  • Unplug all fibre cable from the server (or other disks than the OS)
  • Boot on Solaris 10 Install DVD
  • On boot Select option 6 : "Start Single User Shell"
  • It will scan for existing zpool containing os installation then ask you if you want to mount your rpool to /a. answer "yes"
  • When you get the prompt, launch this to check the status of the rpool :
Command zpool
> zpool status rpool
  pool: rpool
 state: ONLINE
 scrub: none requested
config:
 
        NAME        STATE     READ WRITE CKSUM
        rpool       ONLINE       0     0     0
          c3t0d0s0  ONLINE       0     0     0
 
errors: No known data errors

  • This way we can see all the disks involved in the zpool (here c3t0d0s0). We will reinstall grub on all the disk in the zpool with this command :
Command installgrub
 > installgrub -m /boot/grub/stage1 /boot/grub/stage2 /dev/rdsk/c3t0d0s0
 
 Updating master boot sector destroys existing boot managers (if any). 
 continue (y/n)? y 
 stage1 written to partition 1 sector 0 (abs 96406065) 
 stage2 written to partition 1, 267 sectors starting at 50 (abs 96406115)
 stage1 written to master boot sector

  • Umount the zpool
Command zpool
zpool export rpool

  • Plug back the fibre cables
  • Reboot
Command init
init 6

That's it !

8 Ressources

http://fr.wikipedia.org/wiki/ZFS
Documentation ZFS Admin
http://jean-francois.im/2008/04/faulted-argh.html
http://www.sqlpac.com/referentiel/docs/unix-solaris-10-zfs-oracle.htm#L6480