Principes de base de ZFS : stockage et performances

Principes de base de ZFS : stockage et performances

Ce printemps, nous avons déjà abordé certains sujets d'introduction, par exemple, comment vérifier la vitesse de vos disques и qu'est-ce que le RAID. Dans le second d'entre eux, nous avons même promis de continuer à étudier les performances de diverses topologies multidisques dans ZFS. C'est le système de fichiers de nouvelle génération qui est désormais implémenté partout : de Apple à Ubuntu.

Eh bien, aujourd'hui est le meilleur jour pour se familiariser avec ZFS, lecteurs curieux. Sachez simplement que de l'humble avis du développeur OpenZFS Matt Ahrens, "c'est vraiment difficile".

Mais avant d'arriver aux chiffres - et ils le feront, je le promets - pour toutes les options d'une configuration ZFS à huit disques, nous devons parler de comme En général, ZFS stocke les données sur disque.

Zpool, vdev et périphérique

Principes de base de ZFS : stockage et performances
Ce diagramme de pool complet comprend trois vdevs auxiliaires, un de chaque classe et quatre pour RAIDz2

Principes de base de ZFS : stockage et performances
Il n'y a généralement aucune raison de créer un pool de types et de tailles de vdev incompatibles - mais rien ne vous empêche de le faire si vous le souhaitez.

Pour vraiment comprendre le système de fichiers ZFS, vous devez examiner de près sa structure réelle. Premièrement, ZFS unifie les niveaux traditionnels de gestion des volumes et des systèmes de fichiers. Deuxièmement, il utilise un mécanisme transactionnel de copie sur écriture. Ces caractéristiques signifient que le système est structurellement très différent des systèmes de fichiers et des matrices RAID conventionnels. Le premier ensemble de blocs de construction de base à comprendre est le pool de stockage (zpool), le périphérique virtuel (vdev) et le périphérique réel (device).

zpool

Le pool de stockage zpool est la structure ZFS la plus élevée. Chaque pool contient un ou plusieurs périphériques virtuels. À leur tour, chacun d'eux contient un ou plusieurs dispositifs réels (device). Les pools virtuels sont des blocs autonomes. Un ordinateur physique peut contenir deux pools séparés ou plus, mais chacun est complètement indépendant des autres. Les pools ne peuvent pas partager des appareils virtuels.

La redondance de ZFS se situe au niveau du périphérique virtuel, pas au niveau du pool. Il n'y a absolument aucune redondance au niveau du pool - si un vdev de lecteur ou un vdev spécial est perdu, alors tout le pool est perdu avec lui.

Les pools de stockage modernes peuvent survivre à la perte d'un cache ou d'un journal de périphérique virtuel - bien qu'ils puissent perdre une petite quantité de données sales s'ils perdent le journal vdev lors d'une panne de courant ou d'un plantage du système.

Il existe une idée fausse commune selon laquelle les "bandes de données" ZFS sont écrites sur l'ensemble du pool. Ce n'est pas vrai. Zpool n'est pas drôle du tout RAID0, c'est plutôt drôle JBOD avec un mécanisme complexe de distribution variable.

Pour la plupart, les enregistrements sont répartis entre les appareils virtuels disponibles en fonction de l'espace libre disponible, donc en théorie ils seront tous remplis en même temps. Dans les versions ultérieures de ZFS, l'utilisation actuelle de vdev (utilisation) est prise en compte - si un périphérique virtuel est beaucoup plus occupé qu'un autre (par exemple, en raison d'une charge de lecture), il sera temporairement ignoré pour l'écriture, malgré la disponibilité la plus élevée. rapport d'espace.

Le mécanisme de détection d'utilisation intégré aux méthodes d'allocation d'écriture ZFS modernes peut réduire la latence et augmenter le débit pendant les périodes de charge inhabituellement élevée - mais ce n'est pas le cas. carte blanche sur le mélange involontaire de disques durs lents et de disques SSD rapides dans un pool. Un tel pool inégal fonctionnera toujours à la vitesse de l'appareil le plus lent, c'est-à-dire comme s'il était entièrement composé de tels appareils.

vdev

Chaque pool de stockage se compose d'un ou plusieurs périphériques virtuels (périphérique virtuel, vdev). À son tour, chaque vdev contient un ou plusieurs périphériques réels. La plupart des périphériques virtuels sont utilisés pour le stockage de données simple, mais il existe plusieurs classes d'assistance vdev, notamment CACHE, LOG et SPECIAL. Chacun de ces types de vdev peut avoir l'une des cinq topologies suivantes : périphérique unique (périphérique unique), RAIDz1, RAIDz2, RAIDz3 ou miroir (miroir).

RAIDz1, RAIDz2 et RAIDz3 sont des variétés spéciales de ce que les anciens appelleraient RAID à parité double (diagonale). 1, 2 et 3 font référence au nombre de blocs de parité alloués pour chaque bande de données. Au lieu de disques séparés pour la parité, les périphériques virtuels RAIDz distribuent cette parité de manière semi-uniforme sur les disques. Une matrice RAIDz peut perdre autant de disques qu'elle a de blocs de parité ; s'il en perd un autre, il plantera et emportera le pool de stockage avec lui.

Dans les périphériques virtuels en miroir (mirror vdev), chaque bloc est stocké sur chaque périphérique dans le vdev. Bien que les miroirs à deux largeurs soient les plus courants, n'importe quel nombre arbitraire de périphériques peut se trouver dans un miroir - les triples sont souvent utilisés dans les grandes installations pour améliorer les performances de lecture et la tolérance aux pannes. Un miroir vdev peut survivre à n'importe quelle panne tant qu'au moins un périphérique dans le vdev continue de fonctionner.

Les vdevs uniques sont intrinsèquement dangereux. Un tel périphérique virtuel ne survivra pas à une seule panne - et s'il est utilisé comme stockage ou comme vdev spécial, sa panne entraînera la destruction de l'ensemble du pool. Soyez très, très prudent ici.

CACHE, LOG et SPECIAL VAs peuvent être créés en utilisant l'une des topologies ci-dessus - mais rappelez-vous que la perte d'un SPECIAL VA signifie la perte du pool, donc une topologie redondante est fortement recommandée.

dispositif

C'est probablement le terme le plus facile à comprendre dans ZFS - c'est littéralement un périphérique d'accès aléatoire en bloc. N'oubliez pas que les appareils virtuels sont composés d'appareils individuels, tandis qu'un pool est composé d'appareils virtuels.

Les disques - qu'ils soient magnétiques ou à semi-conducteurs - sont les périphériques de bloc les plus courants utilisés comme blocs de construction de vdev. Cependant, tout périphérique avec un descripteur dans /dev fera l'affaire, de sorte que des matrices RAID matérielles entières peuvent être utilisées comme des périphériques séparés.

Un simple fichier brut est l'un des périphériques de bloc alternatifs les plus importants à partir desquels un vdev peut être construit. Groupes de test de fichiers clairsemés est un moyen très pratique de vérifier les commandes de pool et de voir combien d'espace est disponible dans un pool ou un périphérique virtuel d'une topologie donnée.

Principes de base de ZFS : stockage et performances
Vous pouvez créer un pool de test à partir de fichiers épars en quelques secondes - mais n'oubliez pas de supprimer le pool entier et ses composants par la suite

Supposons que vous souhaitiez installer un serveur sur huit disques et que vous prévoyiez d'utiliser des disques de 10 To (~ 9300 Gio) - mais vous ne savez pas quelle topologie correspond le mieux à vos besoins. Dans l'exemple ci-dessus, nous construisons un pool de test à partir de fichiers épars en quelques secondes - et maintenant nous savons qu'un vdev RAIDz2 de huit disques de 10 To fournit 50 Tio de capacité utilisable.

Une autre classe spéciale d'appareils est SPARE (spare). Les périphériques remplaçables à chaud, contrairement aux périphériques ordinaires, appartiennent à l'ensemble du pool et non à un seul périphérique virtuel. Si un vdev du pool tombe en panne et qu'un périphérique de secours est connecté au pool et disponible, il rejoindra automatiquement le vdev concerné.

Une fois connecté au vdev concerné, le périphérique de secours commence à recevoir des copies ou des reconstructions des données qui devraient se trouver sur le périphérique manquant. Dans le RAID traditionnel, cela s'appelle la reconstruction, tandis que dans le ZFS, cela s'appelle la réargenture.

Il est important de noter que les périphériques de rechange ne remplacent pas définitivement les périphériques défaillants. Il ne s'agit que d'un remplacement temporaire pour réduire la durée de dégradation de vdev. Une fois que l'administrateur a remplacé le vdev défaillant, la redondance est restaurée sur ce périphérique permanent, et SPARE est déconnecté du vdev et redevient un disque de secours pour l'ensemble du pool.

Ensembles de données, blocs et secteurs

Le prochain ensemble de blocs de construction à comprendre dans notre parcours ZFS concerne moins le matériel que la manière dont les données elles-mêmes sont organisées et stockées. Nous sautons quelques niveaux ici - comme metaslab - afin de ne pas encombrer les détails tout en conservant une compréhension de la structure globale.

Ensemble de données (ensemble de données)

Principes de base de ZFS : stockage et performances
Lorsque nous créons un jeu de données pour la première fois, il affiche tout l'espace de pool disponible. Ensuite, nous définissons le quota - et changeons le point de montage. La magie!

Principes de base de ZFS : stockage et performances
Zvol est pour la plupart un jeu de données dépouillé de sa couche de système de fichiers, que nous remplaçons ici par un système de fichiers ext4 parfaitement normal.

Un jeu de données ZFS est à peu près identique à un système de fichiers monté standard. Comme un système de fichiers ordinaire, à première vue, il ressemble à "juste un autre dossier". Mais tout comme les systèmes de fichiers montables classiques, chaque ensemble de données ZFS possède son propre ensemble de propriétés de base.

Tout d'abord, un jeu de données peut avoir un quota attribué. Si défini zfs set quota=100G poolname/datasetname, vous ne pourrez pas écrire dans le dossier monté /poolname/datasetname plus de 100 Gio.

Remarquez la présence - et l'absence - de barres obliques au début de chaque ligne ? Chaque jeu de données a sa propre place à la fois dans la hiérarchie ZFS et dans la hiérarchie de montage du système. Il n'y a pas de barre oblique dans la hiérarchie ZFS - vous commencez par le nom du pool, puis le chemin d'accès d'un jeu de données au suivant. Par exemple, pool/parent/child pour un jeu de données nommé child sous le jeu de données parent parent dans un pool avec un nom créatif pool.

Par défaut, le point de montage du jeu de données sera équivalent à son nom dans la hiérarchie ZFS, avec une barre oblique au début - le pool nommé pool monté comme /pool, base de données parent monté dans /pool/parent, et l'ensemble de données enfant child monté dans /pool/parent/child. Cependant, le point de montage système du jeu de données peut être modifié.

Si nous précisons zfs set mountpoint=/lol pool/parent/child, alors le jeu de données pool/parent/child monté sur le système comme /lol.

En plus des jeux de données, il convient de mentionner les volumes (zvols). Un volume est à peu près identique à un jeu de données, sauf qu'il n'a pas réellement de système de fichiers, c'est juste un périphérique bloc. Vous pouvez, par exemple, créer zvol Avec nom mypool/myzvol, puis formatez-le avec un système de fichiers ext4, puis montez ce système de fichiers - vous avez maintenant un système de fichiers ext4, mais avec toutes les fonctionnalités de sécurité de ZFS ! Cela peut sembler idiot sur une seule machine, mais cela a beaucoup plus de sens en tant que backend lors de l'exportation d'un périphérique iSCSI.

Des blocs

Principes de base de ZFS : stockage et performances
Le fichier est représenté par un ou plusieurs blocs. Chaque bloc est stocké sur un périphérique virtuel. La taille du bloc est généralement égale au paramètre taille d'enregistrement, mais peut être réduit à 2^décalages'il contient des métadonnées ou un petit fichier.

Principes de base de ZFS : stockage et performances
Nous sommes réellement vraiment ne plaisante pas sur l'énorme pénalité de performance si vous définissez un décalage trop petit

Dans un pool ZFS, toutes les données, y compris les métadonnées, sont stockées dans des blocs. La taille de bloc maximale pour chaque ensemble de données est définie dans la propriété recordsize (taille d'enregistrement). La taille de l'enregistrement peut être modifiée, mais cela ne changera pas la taille ou l'emplacement des blocs qui ont déjà été écrits dans le jeu de données - cela n'affecte que les nouveaux blocs au fur et à mesure qu'ils sont écrits.

Sauf indication contraire, la taille d'enregistrement par défaut actuelle est de 128 Kio. C'est une sorte de compromis délicat où les performances ne sont pas parfaites, mais ce n'est pas terrible non plus dans la plupart des cas. Recordsize peut être réglé sur n'importe quelle valeur de 4K à 1M (avec des paramètres avancés recordsize vous pouvez en installer encore plus, mais c'est rarement une bonne idée).

Tout bloc fait référence aux données d'un seul fichier - vous ne pouvez pas entasser deux fichiers différents dans un seul bloc. Chaque fichier se compose d'un ou plusieurs blocs, selon la taille. Si la taille du fichier est inférieure à la taille de l'enregistrement, il sera stocké dans une taille de bloc plus petite - par exemple, un bloc avec un fichier de 2 KiB n'occupera qu'un seul secteur de 4 KiB sur le disque.

Si le fichier est suffisamment volumineux et nécessite plusieurs blocs, alors tous les enregistrements avec ce fichier seront de taille recordsize - y compris la dernière entrée, dont la partie principale peut être espace inutilisé.

zvols n'ont pas de propriété recordsize - à la place, ils ont une propriété équivalente volblocksize.

Secteurs

Le dernier élément de base, le plus fondamental, est le secteur. Il s'agit de la plus petite unité physique qui peut être écrite ou lue à partir du périphérique sous-jacent. Pendant plusieurs décennies, la plupart des disques utilisaient des secteurs de 512 octets. Récemment, la plupart des disques sont configurés pour des secteurs de 4 KiB, et certains - en particulier les SSD - ont des secteurs de 8 KiB ou même plus.

Le système ZFS possède une propriété qui vous permet de définir manuellement la taille du secteur. Cette propriété ashift. Un peu déroutant, ashift est une puissance de deux. Par exemple, ashift=9 signifie une taille de secteur de 2^9, ou 512 octets.

ZFS interroge le système d'exploitation pour obtenir des informations détaillées sur chaque périphérique de bloc lorsqu'il est ajouté à un nouveau vdev, et installe théoriquement automatiquement ashift correctement en fonction de ces informations. Malheureusement, de nombreux disques mentent sur leur taille de secteur afin de maintenir la compatibilité avec Windows XP (qui n'a pas pu comprendre les disques avec d'autres tailles de secteur).

Cela signifie qu'il est fortement conseillé à un administrateur ZFS de connaître la taille réelle du secteur de ses périphériques et de définir manuellement ashift. Si ashift est réglé trop bas, le nombre d'opérations de lecture/écriture augmente astronomiquement. Ainsi, écrire des "secteurs" de 512 octets dans un vrai secteur de 4 KiB signifie devoir écrire le premier "secteur", puis lire le secteur de 4 KiB, le modifier avec un deuxième "secteur" de 512 octets, le réécrire dans le nouveau Secteur de 4 Kio, et ainsi de suite pour chaque entrée.

Dans le monde réel, une telle pénalité frappe les SSD Samsung EVO, pour lesquels ashift=13, mais ces SSD mentent sur leur taille de secteur, et donc la valeur par défaut est définie sur ashift=9. Si un administrateur système expérimenté ne modifie pas ce paramètre, ce SSD fonctionne plus lent disque dur magnétique conventionnel.

A titre de comparaison, pour une taille trop grande ashift il n'y a pratiquement pas de sanction. Il n'y a pas de véritable pénalité de performance et l'augmentation de l'espace inutilisé est infinitésimale (ou nulle avec la compression activée). Par conséquent, nous recommandons fortement que même les lecteurs qui utilisent des secteurs de 512 octets installent ashift=12 ou ashift=13pour affronter l'avenir avec confiance.

propriété ashift est défini pour chaque périphérique virtuel vdev, et pas pour la piscine, comme beaucoup le pensent à tort - et ne change pas après l'installation. Si vous frappez accidentellement ashift lorsque vous ajoutez un nouveau vdev à un pool, vous avez irrémédiablement pollué ce pool avec un périphérique peu performant et il n'y a généralement pas d'autre choix que de détruire le pool et de recommencer. Même la suppression de vdev ne vous sauvera pas d'une configuration cassée ashift!

Mécanisme de copie sur écriture

Principes de base de ZFS : stockage et performances
Si un système de fichiers normal doit écraser des données, il modifie chaque bloc où il se trouve.

Principes de base de ZFS : stockage et performances
Un système de fichiers de copie sur écriture écrit une nouvelle version de bloc, puis déverrouille l'ancienne version

Principes de base de ZFS : stockage et performances
Dans l'abstrait, si nous ignorons l'emplacement physique réel des blocs, alors notre "comète de données" est simplifiée en un "ver de données" qui se déplace de gauche à droite sur la carte de l'espace disponible

Principes de base de ZFS : stockage et performances
Nous pouvons maintenant avoir une bonne idée du fonctionnement des instantanés de copie sur écriture - chaque bloc peut appartenir à plusieurs instantanés et persistera jusqu'à ce que tous les instantanés associés soient détruits

Le mécanisme de copie sur écriture (CoW) est la base fondamentale de ce qui fait de ZFS un système si étonnant. Le concept de base est simple - si vous demandez à un système de fichiers traditionnel de modifier un fichier, il fera exactement ce que vous avez demandé. Si vous demandez à un système de fichiers de copie sur écriture de faire la même chose, il dira "ok" mais vous mentira.

Au lieu de cela, un système de fichiers de copie sur écriture écrit une nouvelle version du bloc modifié, puis met à jour les métadonnées du fichier pour dissocier l'ancien bloc et lui associer le nouveau bloc que vous venez d'écrire.

Détacher l'ancien bloc et lier le nouveau se fait en une seule opération, il ne peut donc pas être interrompu - si vous éteignez après cela, vous avez une nouvelle version du fichier, et si vous éteignez tôt, vous avez l'ancienne version . Dans tous les cas, il n'y aura pas de conflits dans le système de fichiers.

La copie sur écriture dans ZFS se produit non seulement au niveau du système de fichiers, mais également au niveau de la gestion des disques. Cela signifie que ZFS n'est pas affecté par les espaces blancs (un trou dans le RAID) - un phénomène lorsque la bande n'a eu le temps que partiellement d'enregistrer avant que le système ne tombe en panne, avec des dommages au tableau après un redémarrage. Ici, la bande est écrite de manière atomique, vdev est toujours séquentiel et Bob est ton oncle.

ZIL : journal d'intention ZFS

Principes de base de ZFS : stockage et performances
Le système ZFS traite les écritures synchrones d'une manière spéciale - il les stocke temporairement mais immédiatement dans ZIL avant de les écrire de manière permanente plus tard avec les écritures asynchrones.

Principes de base de ZFS : stockage et performances
En règle générale, les données écrites dans un ZIL ne sont jamais lues à nouveau. Mais c'est possible après un plantage du système

Principes de base de ZFS : stockage et performances
SLOG, ou périphérique LOG secondaire, est juste un vdev spécial - et de préférence très rapide -, où le ZIL peut être stocké séparément du stockage principal

Principes de base de ZFS : stockage et performances
Après un crash, toutes les données sales dans ZIL sont rejouées - dans ce cas, ZIL est sur SLOG, donc elles sont rejouées à partir de là

Il existe deux catégories principales d'opérations d'écriture - synchrone (sync) et asynchrone (async). Pour la plupart des charges de travail, la grande majorité des écritures sont asynchrones - le système de fichiers permet de les agréger et de les émettre par lots, ce qui réduit la fragmentation et augmente considérablement le débit.

Les enregistrements synchronisés sont une question complètement différente. Lorsqu'une application demande une écriture synchrone, elle indique au système de fichiers : "Vous devez valider ceci dans la mémoire non volatile maintenantjusque-là, je ne peux rien faire d'autre." Par conséquent, les écritures synchrones doivent être validées sur le disque immédiatement, et si cela augmente la fragmentation ou réduit le débit, qu'il en soit ainsi.

ZFS gère les écritures synchrones différemment des systèmes de fichiers ordinaires : au lieu de les valider immédiatement dans un stockage normal, ZFS les valide dans une zone de stockage spéciale appelée ZFS Intent Log, ou ZIL. L'astuce est que ces enregistrements également restent en mémoire, étant agrégés avec les demandes d'écriture asynchrones normales, pour être ensuite vidés vers le stockage en tant que TXG (groupes de transactions) parfaitement normaux.

En fonctionnement normal, le ZIL est écrit et n'est plus jamais relu. Lorsque, après quelques instants, les enregistrements du ZIL sont engagés dans le stockage principal dans des TXG ordinaires de la RAM, ils sont détachés du ZIL. Le seul moment où quelque chose est lu à partir du ZIL est lorsque le pool est importé.

Si ZFS échoue - une panne du système d'exploitation ou une panne de courant - alors qu'il y a des données dans le ZIL, ces données seront lues lors de la prochaine importation du pool (par exemple, lorsque le système d'urgence est redémarré). Tout ce qui se trouve dans le ZIL sera lu, regroupé en TXG, validé dans le stockage principal, puis détaché du ZIL pendant le processus d'importation.

L'une des classes d'assistance vdev s'appelle LOG ou SLOG, le périphérique secondaire de LOG. Il a un seul but - fournir au pool un vdev séparé, et de préférence beaucoup plus rapide et très résistant à l'écriture pour stocker le ZIL, au lieu de stocker le ZIL sur le magasin vdev principal. Le ZIL lui-même se comporte de la même manière, quel que soit l'endroit où il est stocké, mais si le vdev LOG a des performances d'écriture très élevées, les écritures synchrones seront plus rapides.

L'ajout d'un vdev avec LOG au pool ne fonctionne pas ne peut pas améliorer les performances d'écriture asynchrone - même si vous forcez toutes les écritures sur ZIL avec zfs set sync=always, ils seront toujours liés au stockage principal dans TXG de la même manière et au même rythme que sans le journal. La seule amélioration directe des performances est la latence des écritures synchrones (car un journal plus rapide accélère les opérations). sync).

Cependant, dans un environnement qui nécessite déjà de nombreuses écritures synchrones, vdev LOG peut indirectement accélérer les écritures asynchrones et les lectures non mises en cache. Le déchargement des entrées ZIL vers un vdev LOG séparé signifie moins de conflits pour les IOPS sur le stockage principal, ce qui améliore dans une certaine mesure les performances de toutes les lectures et écritures.

Instantanés

Le mécanisme de copie sur écriture est également une base nécessaire pour les instantanés atomiques ZFS et la réplication asynchrone incrémentielle. Le système de fichiers actif a une arborescence de pointeurs qui marque tous les enregistrements avec les données actuelles - lorsque vous prenez un instantané, vous faites simplement une copie de cette arborescence de pointeurs.

Lorsqu'un enregistrement est écrasé sur le système de fichiers actif, ZFS écrit d'abord la nouvelle version de bloc dans l'espace inutilisé. Il détache ensuite l'ancienne version du bloc du système de fichiers actuel. Mais si un instantané fait référence à l'ancien bloc, il reste inchangé. L'ancien bloc ne sera pas réellement restauré en tant qu'espace libre tant que tous les instantanés faisant référence à ce bloc n'auront pas été détruits !

réplication

Principes de base de ZFS : stockage et performances
Ma bibliothèque Steam en 2015 était de 158 Gio et comprenait 126 927 fichiers. C'est assez proche de la situation optimale pour rsync - la réplication ZFS sur le réseau n'était "que" 750% plus rapide.

Principes de base de ZFS : stockage et performances
Sur le même réseau, la réplication d'un seul fichier image de machine virtuelle Windows 40 de 7 Go est une histoire complètement différente. La réplication ZFS est 289 fois plus rapide que rsync - ou "seulement" 161 fois plus rapide si vous êtes assez intelligent pour appeler rsync avec --inplace.

Principes de base de ZFS : stockage et performances
Lorsqu'une image de machine virtuelle est mise à l'échelle, rsync génère une mise à l'échelle avec elle. 1,9 Tio n'est pas si important pour une image de machine virtuelle moderne - mais il est suffisamment important pour que la réplication ZFS soit 1148 XNUMX fois plus rapide que rsync, même avec l'argument --inplace de rsync

Une fois que vous avez compris le fonctionnement des instantanés, il devrait être facile de saisir l'essence de la réplication. Puisqu'un instantané n'est qu'un arbre de pointeurs vers des enregistrements, il s'ensuit que si nous le faisons zfs send instantané, nous envoyons à la fois cet arbre et tous les enregistrements qui lui sont associés. Quand nous envoyons ceci zfs send в zfs receive sur la cible, il écrit à la fois le contenu réel du bloc et l'arborescence des pointeurs qui font référence aux blocs vers l'ensemble de données cible.

Les choses deviennent encore plus intéressantes à la seconde zfs send. Nous avons maintenant deux systèmes, chacun contenant poolname/datasetname@1, et vous prenez un nouvel instantané poolname/datasetname@2. Par conséquent, dans la piscine d'origine, vous avez datasetname@1 и datasetname@2, et dans le pool cible jusqu'à présent, seul le premier instantané datasetname@1.

Puisque nous avons un instantané commun entre la source et la cible datasetname@1, on peut le faire incrémentale zfs send au-dessus. Quand on dit au système zfs send -i poolname/datasetname@1 poolname/datasetname@2, il compare deux arbres de pointeurs. Tous les pointeurs qui n'existent que dans @2, se réfèrent évidemment à de nouveaux blocs - nous avons donc besoin du contenu de ces blocs.

Sur un système distant, le traitement d'un send tout aussi simple. Nous écrivons d'abord toutes les nouvelles entrées incluses dans le flux send, puis ajoutez des pointeurs vers ces blocs. Voila, nous avons @2 dans le nouveau système !

La réplication incrémentielle asynchrone ZFS est une amélioration considérable par rapport aux méthodes antérieures non basées sur des instantanés telles que rsync. Dans les deux cas, seules les données modifiées sont transférées - mais rsync doit d'abord lire le à partir du disque toutes les données des deux côtés pour vérifier la somme et la comparer. En revanche, la réplication ZFS ne lit que les arborescences de pointeurs - et tous les blocs qui ne sont pas présents dans l'instantané partagé.

compression intégrée

Le mécanisme de copie sur écriture simplifie également le système de compression en ligne. Dans un système de fichiers traditionnel, la compression est problématique - l'ancienne version et la nouvelle version des données modifiées résident dans le même espace.

Si nous considérons un morceau de données au milieu d'un fichier qui commence sa vie comme un mégaoctet de zéros à partir de 0x00000000 et ainsi de suite, il est très facile de le compresser dans un secteur sur le disque. Mais que se passe-t-il si nous remplaçons ce mégaoctet de zéros par un mégaoctet de données incompressibles comme JPEG ou un bruit pseudo-aléatoire ? De manière inattendue, ce mégaoctet de données nécessitera non pas un, mais 256 secteurs de 4 Ko, et à cet endroit sur le disque, un seul secteur est réservé.

ZFS n'a pas ce problème, car les enregistrements modifiés sont toujours écrits dans l'espace inutilisé - le bloc d'origine n'occupe qu'un secteur de 4 KiB, et le nouvel enregistrement en occupera 256, mais ce n'est pas un problème - un fragment récemment modifié du " milieu" du fichier serait écrit dans l'espace inutilisé, que sa taille ait changé ou non, donc pour ZFS, c'est une situation assez courante.

La compression ZFS native est désactivée par défaut et le système propose des algorithmes enfichables, actuellement LZ4, gzip (1-9), LZJB et ZLE.

  • LZ4 est un algorithme de streaming qui offre une compression et une décompression extrêmement rapides et des avantages en termes de performances pour la plupart des cas d'utilisation, même sur des processeurs assez lents.
  • GZIP est un algorithme vénérable que tous les utilisateurs d'Unix connaissent et apprécient. Il peut être implémenté avec des niveaux de compression de 1 à 9, le taux de compression et l'utilisation du processeur augmentant à mesure qu'il approche du niveau 9. L'algorithme est bien adapté à tous les cas d'utilisation de texte (ou d'autres cas hautement compressibles), mais sinon, il provoque souvent des problèmes de processeur - utilisez-le avec précaution, surtout aux niveaux supérieurs.
  • LZJB est l'algorithme original de ZFS. Il est obsolète et ne devrait plus être utilisé, le LZ4 le surpasse en tout point.
  • MAL - codage de niveau zéro, codage de niveau zéro. Il ne touche pas du tout aux données normales, mais comprime de grandes séquences de zéros. Utile pour les ensembles de données complètement incompressibles (tels que JPEG, MP4 ou d'autres formats déjà compressés) car il ignore les données incompressibles mais comprime l'espace inutilisé dans les enregistrements résultants.

Nous recommandons la compression LZ4 pour presque tous les cas d'utilisation ; la pénalité de performance lors de la rencontre de données incompressibles est très faible, et gagner les performances pour les données typiques sont significatives. Copier une image de machine virtuelle pour une nouvelle installation du système d'exploitation Windows (OS fraîchement installé, pas encore de données à l'intérieur) avec compression=lz4 passé 27% plus vite qu'avec compression=nonedans ce test en 2015.

ARC - cache de remplacement adaptatif

ZFS est le seul système de fichiers moderne que nous connaissons qui utilise son propre mécanisme de mise en cache de lecture, plutôt que de s'appuyer sur le cache de page du système d'exploitation pour stocker des copies des blocs récemment lus dans la RAM.

Bien que le cache natif ne soit pas sans problèmes - ZFS ne peut pas répondre aux nouvelles demandes d'allocation de mémoire aussi rapidement que le noyau, donc le nouveau défi malloc() sur l'allocation de mémoire peut échouer s'il a besoin de la RAM actuellement occupée par ARC. Mais il y a de bonnes raisons d'utiliser votre propre cache, du moins pour l'instant.

Tous les systèmes d'exploitation modernes connus, y compris MacOS, Windows, Linux et BSD, utilisent l'algorithme LRU (Least Récemment Utilisé) pour implémenter le cache de page. Il s'agit d'un algorithme primitif qui pousse le bloc mis en cache "dans la file d'attente" après chaque lecture, et pousse les blocs "dans la file d'attente" au besoin pour ajouter de nouveaux échecs de cache (blocs qui auraient dû être lus à partir du disque, pas du cache) en haut.

L'algorithme fonctionne généralement bien, mais sur les systèmes avec de grands ensembles de données de travail, LRU conduit facilement au thrashing - évinçant les blocs fréquemment nécessaires pour faire de la place pour les blocs qui ne seront plus jamais lus à partir du cache.

ARC est un algorithme beaucoup moins naïf qui peut être considéré comme un cache "pondéré". Chaque fois qu'un bloc en cache est lu, il devient un peu "plus lourd" et plus difficile à expulser - et même après avoir expulsé un bloc suivi dans un certain laps de temps. Un bloc qui a été évincé mais qui doit ensuite être relu dans le cache deviendra également "plus lourd".

Le résultat final de tout cela est un cache avec un taux de succès beaucoup plus élevé, le rapport entre les succès du cache (lectures effectuées à partir du cache) et les échecs du cache (lectures à partir du disque). Il s'agit d'une statistique extrêmement importante - non seulement les accès au cache eux-mêmes sont servis plus rapidement, mais les échecs de cache peuvent également être traités plus rapidement, car plus il y a d'accès au cache, moins il y a de demandes de disque simultanées et plus la latence est faible pour les échecs restants qui doivent être servi avec disque.

Conclusion

Après avoir appris la sémantique de base de ZFS - comment fonctionne la copie sur écriture, ainsi que les relations entre les pools de stockage, les périphériques virtuels, les blocs, les secteurs et les fichiers - nous sommes prêts à discuter des performances réelles avec des nombres réels.

Dans la partie suivante, nous examinerons les performances réelles des pools avec vdevs et RAIDz en miroir, les unes par rapport aux autres, ainsi que par rapport aux topologies RAID traditionnelles du noyau Linux que nous avons explorées. plus tôt.

Au début, nous voulions couvrir uniquement les bases - les topologies ZFS elles-mêmes - mais après un tel préparons-nous à parler d'une configuration et d'un réglage plus avancés de ZFS, y compris l'utilisation de types de vdev auxiliaires tels que L2ARC, SLOG et l'allocation spéciale.

Source: habr.com

Ajouter un commentaire