11.12. Optimiser les disques

11.12.1. Les variables sysctl

11.12.1.1. vfs.vmiodirenable

La variable sysctl vfs.vmiodirenable peut être positionnée soit à 0 (désactivée) soit à 1 (activée); elle est a 1 par défaut. Cette variable spécifie comment les répertoires sont cachés par le système. La plupart des répertoires sont petits, utilisant juste un simple fragment du système de fichiers (typiquement 1KO) et moins dans le cache en mémoire (typiquement 512 octets). Avec cette variable désactivée (à 0), le cache en mémoire ne cachera qu'un nombre fixe de répertoires même si vous disposez d'une grande quantité de mémoire. Activée (à 1), cette variable sysctl permet au cache en mémoire d'utiliser le cache des pages de mémoire virtuelle pour cacher les répertoires, rendant toute la mémoire disponible pour cacher les répertoires. Cependant, la taille minimale de l'élément mémoire utilisé pour cacher un répertoire est une page physique (typiquement 4KO) plutôt que 512 octets. Nous recommandons de conserver de cette option activée si vous faites fonctionner des services qui manipulent un grand nombre de fichiers. De tels services peuvent être des caches web, d'importants systèmes de courrier électronique, et des systèmes serveurs de groupe de discussion. Conserver cette option activée ne réduira généralement pas les performances même avec la mémoire gaspillée mais vous devriez faire des expériences pour le déterminer.

11.12.1.2. vfs.write_behind

La variable sysctl vfs.write_behind est positionnée par défaut à 1 (activée). Elle demande au système de fichiers d'effectuer les écritures lorsque des grappes complètes de données ont été collectées, ce qui se produit généralement lors de l'écriture séquentielle de gros fichiers. L'idée est d'éviter de saturer le cache tampon avec des tampons sales quand cela n'améliorera pas les performances d'E/S. Cependant, cela peut bloquer les processus et dans certaines conditions vous pouvez vouloir désactiver cette fonction.

11.12.1.3. vfs.hirunningspace

La variable sysctl vfs.hirunningspace détermine combien d'opérations d'écriture peuvent être mises en attente à tout moment au niveau des contrôleurs disques du système. La valeur par défaut est normalement suffisante mais sur les machines avec de nombreux disques, vous pouvez vouloir l'augmenter jusqu'à quatre ou cinq méga-octets. Notez que fixer une valeur trop élevée (dépassant la limite d'écriture du cache tampon) peut donner lieu à de très mauvaises performances. Ne fixez pas cette valeur à une valeur élevée arbitraire! Des valeurs d'écriture élevées peuvent ajouter des temps de latence aux opérations d'écriture survenant au même moment.

Il existent d'autres variables sysctl relatives aux caches tampons et aux pages VM. Nous ne recommandons pas de modifier ces valeurs, le système VM effectue un très bon travail d'auto-optimisation.

11.12.1.4. vm.swap_idle_enabled

La variable vm.swap_idle_enabled est utile dans le cas de systèmes multi-utilisateurs importants où il y a beaucoup d'utilisateurs s'attachant et quittant le système et de nombreux processus inactifs. De tels systèmes tendent à générer une pression assez importante et continue sur les réserves de mémoire libres. Activer cette fonction et régler l'hystéresis de libération de l'espace de pagination (en secondes d'inactivité) par l'intermédiaire des variables vm.swap_idle_threshold1 et vm.swap_idle_threshold2, vous permet de diminuer la priorité des pages mémoire associées avec les processus inactifs plus rapidement qu'avec l'algorithme normal de libération. Cela aide le “daemon” de libération des pages. N'activez cette option que si vous en besoin, parce que la concession que vous faites est d'utiliser l'espace de pagination pour les pages mémoire plus tôt qu'à l'accoutumé, consommant par conséquent plus d'espace de pagination et de bande passante disque. Sur un petit système, cette option aura un effet limité mais dans le cas d'un système important qui fait appel à l'espace de pagination de façon modérée, cette option permettra au système VM de transférer l'ensemble des processus de et vers la mémoire aisément.

11.12.1.5. hw.ata.wc

FreeBSD 4.3 a flirté avec la désactivation du cache en écriture des disques IDE. Cela réduisit la bande passante en écriture des disques IDE mais fut considéré comme nécessaire en raison de sérieux problèmes de cohérence de données introduits par les fabricants de disques durs. Le problème est que les disques IDE mentent sur le moment où une écriture est réellement terminée. Avec le cache en écriture IDE activé, les disques durs IDE non seulement n'écriront pas les données dans l'ordre, mais parfois retarderont l'écriture de certains blocs indéfiniment sous une charge disque importante. Un crash ou une coupure secteur pourra être à l'origine de sérieuses corruptions du système de fichiers. Par précaution le paramétrage par défaut de FreeBSD fut modifié. Malheureusement, le résultat fut une telle perte de performances que nous avons réactivé le cache en écriture après cette version de FreeBSD. Vous devriez contrôler la valeur par défaut sur votre système en examinant la variable sysctl hw.ata.wc. Si le cache en écriture des disques IDE est désactivé, vous pouvez le réactiver en positionnant la variable à 1. Cela doit être fait à partir du chargeur au démarrage. Tenter de le faire après le démarrage du noyau n'aura aucun effet.

Pour plus d'informations, veuillez consulter la page de manuel ata(4).

11.12.1.6. SCSI_DELAY (kern.cam.scsi_delay)

L'option de configuration du noyau SCSI_DELAY peut être utilisée pour réduire le temps de démarrage du système. Le délai par défaut est important et peut être responsable de plus de 15 secondes d'attente lors du processus de démarrage. Réduire ce délai à 5 secondes est généralement suffisant (tout particulièrement avec les disques modernes). Les versions de FreeBSD récentes (5.0 et suivantes) devraient utiliser l'option de démarrage kern.cam.scsi_delay. Cette option de démarrage et celle de configuration du noyau acceptent des valeurs en millisecondes et non pas en secondes.

11.12.2. Les “Soft Updates”

Le programme tunefs(8) peut être utilisé pour régler finement un système de fichiers. Ce programme dispose de nombreuses options différentes, mais pour l'instant nous nous intéresserons uniquement à l'activation et la désactivation des “Soft Updates”, ce qui fait avec:

# tunefs -n enable /filesystem
# tunefs -n disable /filesystem

Un système de fichiers ne peut être modifié avec tunefs(8) tant qu'il est monté. Un bon moment pour activer les “Soft Updates” est avant que les partitions ne soient montées en mode mono-utilisateur.

Les “Soft Updates” améliorent de façon drastique les performances sur les méta-données, principalement la création et la suppression de fichier, par l'utilisation d'un cache mémoire. Nous recommandons d'activer les “Soft Updates” sur tous vos systèmes de fichiers. Il y a deux inconvénients aux “Soft Updates” que vous devez connaître: tout d'abord, les “Soft Updates” garantissent la cohérence du système de fichiers en cas de crash mais pourront facilement être en retard de quelques secondes (voir même une minute!) dans la mise à jour du disque. Si votre système plante il se peut que vous perdiez plus de travail que dans d'autres cas. Deuxièmement, les “Soft Updates” retardent la libération des blocs du système de fichiers. Si vous avez un système de fichiers (comme le système de fichiers racine) qui est presque plein, effectuer une mise à jour majeure, comme un make installworld, peut mener à un manque d'espace sur le système de fichiers et faire échouer la mise à jour.

11.12.2.1. Plus de détails à propos des “Soft Updates”

Il y a deux approches traditionnelles pour écrire les méta-données d'un système de fichiers sur le disque (mise à jour des méta-données et mise à jour des éléments sans données comme les inodes ou les répertoires).

Historiquement, le comportement par défaut était d'écrire les mises à jour des méta-données de façon synchrone. Si un répertoire a été modifié, le système attendait jusqu'à ce que le changement soit effectivement écrit sur le disque. Les tampons des données de fichier (contenu du fichier) passaient par le cache mémoire et étaient copiés sur le disque plus tard de façon asynchrone. L'avantage de cette implémentation est qu'elle est effectuée sans risque. S'il y a un problème durant une mise à jour, les méta-données sont toujours dans un état consistant. Un fichier est soit créé complètement soit pas du tout. Si les blocs de données d'un fichier n'ont pas trouvé leur chemin du cache mémoire vers le disque au moment du crash, fsck(8) est capable de s'en apercevoir et de réparer le système de fichiers en fixant la taille du fichier à 0. De plus, l'implémentation est claire et simple. L'inconvénient est que la modification des méta-données est lente. Un rm -r, par exemple, touche à tous les fichiers dans un répertoire séquentiellement, mais chaque modification du répertoire (effacement d'un fichier) sera écrite de façon synchrone sur le disque. Cela comprend les mises à jour du répertoire lui-même, de la table des inodes, et éventuellement celles sur des blocs indirects alloués par le fichier. Des considérations semblables s'appliquent à la création d'importantes hiérarchies ((tar -x).

Le deuxième cas est la mise à jour asynchrone des méta-données. C'est le comportement par défaut de Linux/ext2fs et de l'usage de mount -o async pour l'UFS des systèmes BSD. Toutes les mises à jour des méta-données passent également par l'intermédiaire d'un cache mémoire, c'est à dire, qu'elles seront mélangées aux mises à jour des données du contenu du fichier. L'avantage de cette implémentation est qu'il n'y a pas besoin d'attendre jusqu'à l'écriture sur le disque de chaque mise à jour de méta-données, donc toutes les opérations qui sont à l'origine d'une grande quantité de mise à jour de méta-données fonctionnent bien plus rapidement que dans le cas synchrone. De plus, l'implémentation est toujours claire et simple, il y a donc peu de risque qu'un bogue se cache dans le code. L'inconvénient est qu'il n'y a aucune garantie du tout sur la cohérence du système de fichiers. S'il y a un problème durant une opération qui met à jour une grande quantité de méta-données (comme une coupure secteur, ou quelqu'un appuyant sur le bouton reset), le système de fichiers sera laissé dans un état imprévisible. Il n'y a aucune opportunité d'examiner l'état du système de fichiers quand le système est à nouveau relancé; les blocs de données d'un fichier pourraient déjà avoir été inscrits sur le disque alors que la mise à jour de la table des inodes ou du répertoire associé n'a pas été faite. Il est en fait impossible d'implémenter un fsck qui est capable de nettoyer le chaos résultant (parce que l'information nécessaire n'est pas disponible sur le disque). Si le système de fichiers a été endommagé irrémédiablement, le seul choix est de le recréer avec newfs(8) et de récupérer les données à partir de sauvegardes.

La solution commune pour ce problème fut d'implémenter une région de trace, dont on fait souvent référence sous le terme de journalisation, bien que ce terme ne soit pas toujours utilisé de façon cohérente et est occasionnellement utilisé pour d'autres formes de transaction avec trace. Les mises à jour des méta-données sont toujours écrites de façon synchrone, mais seulement sur une petite région du disque. Elles seront plus tard déplacées vers leur emplacement correct. Parce que la région de trace est une petite région contiguë sur le disque, il n'y a pas de grandes distances de déplacement pour les têtes des disques, même durant les opérations importantes, donc ces opérations sont plus rapides que les mises à jour synchrones. De plus la complexité de l'implémentation est relativement limitée, donc le risque de présence de bogues est faible. Un inconvénient est que toutes les méta-données sont écrites deux fois (une fois dans la région de trace et une fois sur l'emplacement correct) donc pour un fonctionnement normal, une baisse des performances pourra en résulter. D'autre part, dans le cas d'un crash, toutes les opérations sur les méta-données en attente peuvent rapidement être annulées ou complétées à partir de la zone de trace après le redémarrage du système, ayant pour résultat un démarrage rapide du système de fichiers.

Kirk McKusick, le développeur du FFS de Berkeley, a résolu le problème avec les “Soft Updates”: toutes les mises à jour des méta-données sont conservées en mémoire et inscrites sur le disque selon une séquence ordonnée (“mise à jour ordonnée des méta-données”). Ceci a pour effet, dans le cas d'un nombre d'opérations sur les méta-données important, que les dernières mises à jour sur un élément “attrapent” les premières si ces dernières sont encore en mémoire et n'ont pas encore été inscrites sur le disque. Donc toutes les opérations sur, par exemple, un répertoire sont généralement effectuées en mémoire avant que la mise à jour ne soit écrite sur le disque (les blocs de données sont ordonnés en fonction de leur position de sorte à ce qu'ils ne soient pas sur le disque avant leur méta-données). Si le système crash, cela provoque un “retour dans les traces” implicite: toutes les opérations qui n'ont pas trouvé leur chemin vers le disque apparaissent comme si elles n'avaient jamais existé. Un état cohérent du système de fichiers est maintenu et apparaît comme étant celui de 30 ou 60 secondes plus tôt. L'algorithme utilisé garantie que toutes les ressources utilisées soient marquées avec leur bons “bitmaps”: blocs et inodes. Après un crash, les seules erreurs d'allocation de ressources qui apparaissent sont les ressources qui ont été marquées comme “utilisées” et qui sont en fait ”libre”. fsck(8) reconnaît cette situation, et libère les ressources qui ne sont plus utilisées. On peut ignorer sans risque l'état “sale” d'un système de fichiers après un crash en forçant son montage avec mount -f. Afin de libérer les ressources qui peuvent être inutilisées, fsck(8) doit être exécuté plus tard. C'est l'idée qu'il y a derrière le “background fsck” (fsck en tâche de fond): au démarrage du système, seule un “snapshot” (photographie) du système de fichiers est prise. La commande fsck peut être exécutée plus tard sur ce système de fichiers. Tous les systèmes de fichiers peuvent être montés “sales”, donc le système passe en mode multi-utilisateurs. Ensuite, les fsck en tâche de fond seront programmés pour tous les systèmes de fichiers pour lesquels c'est nécessaire, pour libérer les ressources qui peuvent être inutilisées (les systèmes qui n'utilisent pas les ‘Soft Updates” ont toujours besoin du fsck en avant plan).

L'avantage est que les opérations sur les méta-données sont presque aussi rapides que les mises à jour asynchrones (i.e. plus rapide qu'avec le “logging” - traçage, qui doit écrire les méta-données deux fois). Les inconvénients sont la complexité du code (impliquant un haut risque de bogues dans une zone qui est hautement sensible en raison de risque perte de données utilisateur), et une plus grande consommation en mémoire. De plus il y a quelques particularités que l'on peut rencontrer lors de l'utilisation. Après un crash, l'état du système apparaît être en quelque sorte “plus vieux”. Dans des situations où l'approche synchrone classique aurait donné lieu à des fichiers de taille nulle restant après le fsck, ces fichiers n'existent pas du tout avec un système de fichiers utilisant les “Soft Updates” parce que ni les méta-données ni les contenus de fichiers n'ont jamais été inscrits sur le disque. L'espace disque n'est pas rendu tant que les mises à jour n'ont pas été inscrites sur le disque, ce qui peut se produire quelques temps après l'exécution de rm. Cela peut être à l'origine de problèmes quand on installe une grande quantité de données sur un système de fichiers qui ne dispose pas de suffisamment d'espace pour contenir tous les fichiers deux fois.

Ce document, ainsi que d'autres peut être téléchargé sur ftp.FreeBSD.org/pub/FreeBSD/doc/.

Pour toutes questions à propos de FreeBSD, lisez la documentation avant de contacter <questions@FreeBSD.org>.
Pour les questions sur cette documentation, contactez <doc@FreeBSD.org>.