performance du stockage

De Linux France
Aller à : navigation, rechercher

Objectif

Mesurer les performances d'une chaîne d'entrées/sorties, en particulier d'un périphérique en mode bloc (disque dur...).

Autres sources d'information:

Approche

Couches

Ne pas négliger que l'on emploie un périphérique de stockage via une chaîne de composants (chacun interagissant avec celui qui le suit et celui qui le précède dans cette liste):

  • un programme
  • (souvent) un système de fichier
  • (parfois) une ou plusieurs couches logicielles assurant par exemple du partitionnement, du RAID, du LVM, du chiffrement...
  • diverses fonctionnalités du noyau, en particulier de gestion du buffer cache
  • un ou plusieurs pilotes
  • un groupe plus ou moins fourni et hétérogène de circuits, câbles (nappes), spindles...

Il s'agit souvent de déterminer laquelle (ou lesquelles) de ces couches sont déficientes ou mal paramétrées.

Threads

TODO: importance d'un test multithreadé

Outillage

Installer les outils.

Sous Debian:

 aptitude install sudo atop bonnie++ dstat fio hdparm iotop iozone3 sdparm smartmontools spew sysbench time tiobench

Surveillance des outils

Pour surveiller les tests ouvrir au moins 2 autres terminaux, par exemple grâce à screen, et y invoquer ce qui suit. Les laisser ouverts les examiner de temps à autres durant tout test.

Traces

Invoquer dans un terminal:

cd /var/log ; tail -F kern.log syslog

Avec un syslog bien configuré (c'est le cas par défaut sur toute bonne distribution) cela offre moyen de vérifier que le noyau ne produit pas de message d'erreur relatif à un test.

atop et iotop

Dans un autre terminal invoquer:

atop

En ce qui concerne atop:

  • le configurer de sorte qu'il montre si nécessaire l'activité de tous les périphériques. Pour cela:
    • placer une ligne "maxlinedisk 999" dans son fichier de configuration par défaut nommé ~/.atoprc, qu'il ne lit que s'il est invoqué sans paramètre
    • utiliser la commande interactive l (L minuscule) et répondre "0" à la question "Maximum lines for disk statistics"
  • appuyer sur d (D minuscule) dès qu'il est démarré, pour suivre surtout l'activité des disques.

On peut ainsi vérifier que tous les processus animant les outils sont exécutés et que les périphériques sont bien sollicités comme souhaité.

Autres approches: « iotop -oPa » ou « iotop -o -b -qqq ».

Autres

Autres utilitaires de suivi potentiellement utiles:

  • dstat
  • iostat
  • vmstat

"sdd"

Nous utiliserons "sdd", qui n'est (fin 2012) malheureusement plus disponible sous forme de paquetage Debian officiel, plutôt que le classique "dd" car ses options facilitent la tâche. Si vous préférez employer "dd" toujours utiliser son paramètre "conv=fsync".

"time"

Pour détecter certaines dérives inopportunes, par exemple de l'activité du système ne découlant pas du test donc parasitant peut-être ses résultats, nous lancerons des tests via "time". Cela permet par exemple de constater que le processeur ou la mémoire virtuelle furent sollicités au-delà de ce qu'exige le test.

Le shell «bash» fournit une commande interne "time", que nous emploierons.

Un paquetage (sous Debian nommé "time") offre un utilitaire nommé "time" livrant des informations complètes mais difficiles à interpréter. Celui de bash suffit le plus souvent, toutefois pour obtenir davantage de détails employer cet utilitaire en déclarant un alias de shell:

alias time=/usr/bin/time

Certains préfèrent le "times" du shell.

Pour ne pas employer "time":

alias time=":;"

"sudo"

Lors des tests nous emploierons " sudo". Si vous ne souhaitez pas le faire connectez-vous au système en tant qu'utilisateur "root" (c'est dangereux).

Si vous ne souhaitez pas devoir saisir le mot de passe de root lorsque vous invoquez "sudo" créez un fichier "/etc/sudoers.d/TOTO" (où TOTO est à remplacer par le nom de la machine) une ligne:

moi     ALL=(ALL) NOPASSWD: ALL

En remplaçant "moi" par votre nom de connexion. Puis invoquer « chmod 0440 /etc/sudoers.d/TOTO ».

ZORG

ZORG représente dans ce document un nombre de mégaoctets:

  • inférieur à l'espace de stockage disponible à l'emplacement du test en cours, que l'on peut déterminer en:
    • se plaçant dans un répertoire du système de fichiers dont on veut mesurer les performances
    • invoquant "dh -h ." et vérifiant que l'on se trouve bien dans le système de fichiers voulu, puis en lisant l'espace de stockage disponible (colonne intitulée "Avail" ou "Disp.")
  • au moins 5 fois supérieur à la quantité totale de Mo de mémoire vive perçus par le noyau, que l'on peut déterminer en invoquant "free -mt", puis lisant dans la ligne intitulée "Mem:" la valeur placée dans la colonne "total"

Afin de l'utiliser facilement lier cette valeur à une variable d'environnement (remplacer ci-après 1000 par la valeur adéquate pour vous):

export ZORG=1000

Ne pas laisser les caches parasiter la mesure

Seules nous intéressent les performances des spindles mêmes, pas celles des caches.

Par conséquent avant tout test nous viderons les caches maintenus par le noyau Linux (qui sont les plus gros).

Pour cela déclarons un alias de shell:

alias flbf='sync ; sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"'

Cette façon d'employer "/proc/sys/vm/drop_caches" est documentée.

Cela fausse un peu les mesures effectuées sur le système de fichiers car, lors du test, rend nécessaire de relire certaines métadonnées. Les autres valeurs possibles (1 et 2) ne correspondent semble-t-il pas mieux.

TODO: perfectionner, dans le cas d'un test fs, grâce à uncache

On peut également utiliser le paramètre du noyau (kernel boot parameter) "mem" afin d'interdire à Linux de percevoir une partie de la RAM, de sorte qu'il ne dispose pas de quoi gérer un bon cache. Pour cela commencer par interdire le démarrage (via "init") de tous les programmes inutiles lors du test et réamorcer, puis employer "free" afin de déterminer la quantité de RAM dont le système a besoin, ajouter une marge de sécurité et réamorcer en utilisant la valeur obtenue en tant que paramètre de "mem".

Tests

Commencer par interrompre tous les processus gourmands utilisant le système de fichiers.

LVM

Si LVM est employé (s'en assurer en invoquant sudo vgdisplay) mesurer les performances du volume physique.

Système de fichiers

Mesurer tout d'abord les performances au niveau du système de fichiers.

Déterminer le débit lors d'une écriture séquentielle:

flbf ; time sdd -pg -inull -bs=1M -t count=$ZORG of=sdd.tmp

Si vous employez dd plutôt que sdd:

flbf ; time dd if=/dev/zero of=dd.tmp bs=1M count=$ZORG conv=fsync

Un disque dur contemporain (2012) doit écrire au moins 40 Mo/s (la moitié dans le cas d'un portable).

Déterminer le débit en lecture séquentielle (attention! Dans la commande "sdd" l'argument "of" laisse place à "if"):

flbf ; time sdd -pg -onull -bs=1M -t if=sdd.tmp

Si vous employez dd plutôt que sdd:

flbf ; time dd if=dd.tmp of=/dev/zero bs=1M

Un disque dur contemporain (2012) doit lire au moins 70 Mo/s (le tiers, donc environ 23 Mo/s, dans le cas d'un portable).

Pour affiner la mesure invoquer:

flbf ; time spew --no-tui -b 1M "$ZORG"M sdd.tmp
flbf ; /usr/sbin/bonnie++ -s "$ZORG":1024k -d ./ -f

Swap

Lorsque plusieurs drives abritent le swap il n'est pas nécessaire d'en faire un RAID afin de paralléliser (écrire/lire simultanément sur tous ces drives afin d'améliorer les performances) car la logique de gestion du swap de Linux en est capable grâce aux priorités.

La priorité d'un espace de swap donné (donc le fait qu'il sera utilisé avant un autre) est arithmétiquement proportionnelle à l'indice de priorité qui lui est associé. Explorer les priorités des espaces de swap grâce à «swapon -s».

Pour établir l'indice de priorité d'un espace de swap employer le paramètre -p de swapon, ou pri dans les options de montage (par exemple dans /etc/fstab).

Règles:

  • associer un indice d'autant plus haut que le périphérique offre la plus faible latence, le plus haut débit, la plus fable charge (peu d'autres opérations d'E/S lors des périodes d'utilisation de la swap) et la plus forte résistance (usure faible, robustesse élevée)
  • associer le même indice aux périphériques semblables et distincts. Dans le cas d'un périphérique mécanique, par exemple un disque dur, ne jamais associer le même indice qu'à des spindles différents (pas à des partitions d'un même spindle, sinon les têtes se promèneront entre elles, ce qui ralentira l'ensemble).

Exemple de mauvais paramétrage:

Filename                                Type            Size    Used    Priority
/dev/sda1                               partition       979924  920     -1
/dev/sda2                               partition       768824  920     -1

... c'est mauvais car /dev/sda1 et /dev/sda2 se trouvent sur le même spindle.

Version correcte:

Filename                                Type            Size    Used    Priority
/dev/sda1                               partition       979924  920     -1
/dev/sda2                               partition       768824    0     -2
/dev/sdb1                               partition       867812  920     -1

Spindles

TODO: flbf ; time hdparm -Tt

Pour déterminer la performance de chaque spindle:

for i in `ls NS|grep -v [0-9]` ; do
 flbf ;
 sdd -onull -bs=1M -t count=$ZORG if="$i" ;
 read ;
done

Remplacer NS par un filtre des noms de fichiers spéciaux pertinents, par exemple "/dev/sd*" ou "/dev/hd[a-c,d]".

Liste des noms de fichiers spéciaux associés aux périphériques de stockage:

ls -1 /dev/disk/by-id/ | grep -v -- '-part[0-9]$'

Pour tester simultanément tous les disques SCSI (il faut être logé en tant que root):

flbf ;
ls -1 /dev/disk/by-id/ | grep -v -- '-part[0-9]$' | grep '^scsi' |
 perl -ne
 'chomp ; system "sdd -onull -bs=1M -t count=$ENV{ZORG} -if=/dev/disk/by-id/$_ >& /tmp/$_.sdd &";'

Note: de menus écarts entre disques sont a priori normaux, car en fonction du séquencement des opérations certains bénéficient davantage du buffer cache. Par ailleurs ceux qui stockent les fichiers de résultats sont défavorisés. Autant que faire se peut placer ces fichiers sur un système de fichiers non sollicité par le test (exemple: ">& /tmp/$_.sdd")

TODO: tester accès à partitions, comparer avec perfs lors d'accès au device. Attention aux déplacements (offset de partition différent de celui du début de device) et perfs différentes selon piste du HD => comparer perfs du device et de sa première partition (?)

IOPS: outil de mesure de performance randomio (pas de paquetage Debian, mais ce logiciel est facile à compiler).

SDD (mémoire flash)

Convention: sdX remplacera par la suite le nom du fichier spécial associé à votre drive SSD.

Mettre périodiquement à jour le firmware du SSD.

Noyau

Utiliser un noyau de version 2.6.33 mini (afin de disposer de TRIM], ou bien paramétrer hdparm (explorer le script wiper.sh) afin qu'il gère cet aspect.

S'assurer que le noyau (souvent via udev) est conscient de la nature du SSD installé, en particulier du fait qu'il ne s'agit pas d'un disque:

echo /sys/block/sdX/queue/rotational

S'il l'ignore invoquer (en tant que root):

echo 0 > /sys/block/sdX/queue/rotational

Alignement

Bien aligner les partitions. TODO (vérification grâce à parted)

Cf.

Swap

Ne laisser le noyau utiliser le SSD en tant que swap qu'en dernière extrémité et temporairement, car cela augmente vite l'usure. Jouer pour cela sur la priorité de swap. Exemple:

/NomDuSDD none swap sw,pri=-5 0 0

Système de fichiers

Laisser sur un disque dur ce qui est utilisé de façon intensive ou rémanente, par exemple /tmp (à monter en tmpfs, sauf si la RAM manque) et /var.

Choisir un type de fs adéquat. Par défaut ext4. Explorer Btrfs.

Monter avec les options réduisant les écritures qui vous sont inutiles, en particulier noatime et nodiratime (attention: certains logiciels, par exemple de sauvegarde, n'apprécient pas cela).

Les approches suivantes peuvent rendre les dégâts plus étendus en cas de crash et leur impact sur les performances (en amélioration ou réduction) dépend du profil de charge:

  • Monter sans journal ou log. Avec certains types d'utilisations (fréquents création/destruction/nommage de fichiers/répertoires) cela améliore les performances et réduit l'usure.
  • Monter avec un autosync tardif (paramètre "commit" des options de montage), de façon à augmenter la probabilité que des écritures répétées du même secteur se résoudront en une seule écriture physique.

Pas de read-ahead. En théorie le noyau établit cela, le vérifier grâce à «/sbin/blockdev --getra /dev/sdX» qui doit retourner 0. À défaut:

/sbin/blockdev --setra 0 /dev/sdX

I/O scheduler

Un SDD offre de l'accès direct et non aléatoire, dans le plus gros des cas tout I/O scheduler est inutile, sauf CFQ s'il faut gérer la priorité des E/S (par exemple via ionice):

echo cfq > /sys/block/sdX/queue/scheduler

Pour supprimer tout I/O scheduling remplacer cfq par noop.