Linux : quelques variables intéressantes

La gestion des entrées/sorties fait un important appel à la mémoire pour fluidifier la circulation des données entre les programmes et les disques.

En lecture différents mécanismes permettent de stocker en mémoire le résultat d'un accès disque (en général bien plus "gros" que les données strictement demandées, les disques sont organisés en blocs de 4K et les blocs lus par paquets) ce qui permet lors d'un accès ultérieur séquentiel de pouvoir immédiatement répondre à la demande du programme depuis la mémoire bien plus rapide que le disque. Cela ne pose que peu de problèmes, s'il n'y a pas assez de mémoire pour un programme, la machine libère du cache et y installe le programme. Les données "ecrasées" pourront être relues depuis le disque.

En écriture le même genre de mécanisme est utilisé mais la gestion est beaucoup plus délicate car il faut écrire les données "assez souvent" pour ne pas en perdre sur une coupure ou pour permettre aux autres d'en disposer. Lorsq'un programme effectue un ordre d'écriture le contenu de la demande est stocké en mémoire et le programme est "libéré" pour la suite de son activité. "Un peu plus tard" les données sont écrites physiquement par le système sur le disque. La mémoire ne doit pas être réallouée avant que l'écriture soit entièrement réalisée sur disque, les pages mémoires modifiées sont donc marquées "sales" et ne peuvent être utilisées immédiatement.

Les expressions "assez souvent" et "plus tard" laissent beaucoup d'imprécision, mais en fait il existe un certain nombre de paramètres qui permettent de jouer sur la fréquence de "assez souvent" et sur les éléments qui permettent au système de décider que "plus tard" est arrivé et qu'il doit écrire les données sur le support physique. Voici l'explication de quelques unes de ces variables, qui, comme d'habitude peuvent être modifiées de manière permanente en mettant des valeurs dans "/etc/sysctl.conf" et lues dans /proc/vm/.....

/proc/sys/vm/dirty_writeback_centisecs (default 500) Nombre de "centisecondes" au bout desquelles "pdflush" écrit sur le disque. En général à ne pas toucher.

/proc/sys/vm/dirty_expire_centiseconds (default 3000) Nombre de centisecondes au bout desquelles "pdflush" doit écrire les pages "sales". Le défaut est de 30 secondes --> il y a 30 secondes de décalage entre ecriture logique et physique.

/proc/sys/vm/dirty_background_ratio (default 10 parfois 5) Pourcentage maxi de mémoire utlisé avant que pdflush ecrive. La quantité de mémoire prise en compte est : ( MemFree + Cached - Mapped ) En bref les écritures ne sont réalisées physiquement que quand : - elles on été faites depuis plus de quot;dirty_expire_centiseconds" ou - plus de 10% de ( MemFree + Cached - Mapped ) de la mémoire est utilisé par des pages "sales".

/proc/sys/vm/dirty_ratio (default 40, parfois 20): Pourcentage maxi de la mémoire totale qui peut être utilisé par les pages "sales" avant que le système force les processes à écrire eux-même physiquement au lieu de continuer à générer des écritures en mémoire. Il est à noter que tous les processes sont bloqués en écriture lorsque cela arrive et non pas seulement le process fautif.

Quelques pistes de tuning.

1) D'abord quelques cas "problématiques". En cas d'écriture intensive ou si un ordre "fsync" (utilisé pour synchronisation du file système) arrive il faut synchroniser les fichiers et les métadata cela déclenche un énorme volume d'écriture qui peut bloquer le système pendant un certain temps (le temps que tout soit écrit). Un autre phénomène est le "pompage", un process écrit très vite pendant un certain temps puis ralentit (dès que les écritures physiques commencent) et se maintient à une vitesse de croisière (fonction de la vitesse d'écriture).

2) Quelques pistes de solutions. Adapter les paramètres de gestion des caches. - dirty_background_ratio : le premier à réduire s'il est à 10 le passer à 3 ou 5

- dirty_ratio : on peut parfois constater des améliorations en l'abaissant, mais, là aussi attention aux effets de bord. L'abaissement tend à diminuer la compétition entre différents programmes gros "écriveurs".

- dirty_expire_centisecs : essayer de le réduire un peu, mais il peut y avoir des effets de bord gênants. Trop le réduire (moins de quelques secondes) peut amener à augmenter la quantité d'IO car les pages modifiées sont assez souvent re-modifiées dans la foulée déclenchant une deuxième écriture.

- /proc/sys/vm/dirty_writeback_centisecs : à toucher en dernier recours, il peut être légèrement réduit.

Swapping : Le swapping tend à "virer" dans le swap les processes un peu endormis pour conserver de la mémoire pour les caches. Ce comportement (plus ou moins agressif) peut être contrôlé par le paramètre "swappiness". cf /proc/sys/vm/swappiness 
Augmenter ce paramètre favorise le "swap" et augmente la disponibilité de mémoire pour le cache, le diminuer diminue la disponibilité de mémoire pour le cache mais améliore le réveil des processes un peu endormis.

Autre paramètre. overcommit_memory : visible dans /proc/sys/vm/overcommit_memory (default 0) 
0 = comportement "standard" à préférer dans la plupart des cas 
1 = toujours "over_commiter" à n'utiliser que pour cetaines applications scientifiques 
2 = ne pas over_commiter au delà de la valeur calculée avec overcommit_ratio overcommit_ratio : visible dans /proc/sys/vm/overcommit_ratio (default 50) Ce paramètre donne au système d'allouer plus de mémoire qu'il n'en a. 
Par exemple avec 1GB de RAM et 2GB de swap la mémoire disponible est de 2GB, un "overcommit_ratio" à 50 (50%) permet au système d'allouer (swap + mémoire physique + 50 * (mémoire physique) / 100). 
Dans notre exemple précédent on aurait donc un espace mémoire maxi de 2 + 1 + 0,5 soit 2,5GB. On peut en général le réduire sans inconvénients dans une utilisation normale.

A NOTER :

Certains logiciels n'apprécient pas/peu l'overcommit et peuvent causer problème en manifestant leur mécontentement lorsque les limites approchent.