Améliorer les performances RAID

Il y’a quelque temps je me suis connecté en ssh sur mon serveur et j’ai eu une frayeur, mon RAID5 était en pleine reconstruction…

Ma première à été de vérifier l’état SMART de mes disques mais RAS. J’ai ensuite vérifié plusieurs hypothèses pour finalement arriver à la conclusion que c’était suite à une vérification mensuelle du RAID et qu’il n’y avait là rien d’anormal.

Par contre ce qui m’a choqué c’est le temps nécessaire pour la reconstruction : prés de 3 jours pour 1,8To.

J’ai beau avoir un onduleur sur mon installation, je ne tiens pas vraiment à ce que mon serveur s’arrête en pleine reconstruction et plus cette étape est longue, plus le risque augmente.

J’ai donc passé un peu de temps pour chercher comment accélérer un peu tout ça et vous trouverez ci dessous la synthèse de mes recherches.

  1. Augmenter les limites de vitesses hautes et basses

Le RAID utilise 2 valeurs qui fixent les vitesses hautes et basses vers lesquelles il tend pour éviter de bloquer votre système. Par défaut, ces vitesses sont basses et oblige des temps de reconstruction/Synchronisation assez conséquent sur les gros volumes.

La première étape sera de modifier ces valeurs pour les rendre cohérente avec les performances actuelles du matériel et ce, de manière permanente.

Effectuez une copie de sauvegarde de votre fichier /etc/sysctl.conf :

sudo cp /etc/sysctl.conf /etc/sysctl.conf_ORIG

Editez ensuite ce fichier et insérez-y les lignes suivantes :

echo "dev.raid.speed_limit_min = 51200" | sudo tee -a /etc/sysctl.conf
echo "dev.raid.speed_limit_max = 204800" | sudo tee -a /etc/sysctl.conf

Ces valeurs ne sont pas obligatoires, libre à vous de les adapter à vos besoins.

Enfin, indiquez au système de pendre en compte les nouvelles valeurs :

sudo /sbin/sysctl -p

Votre RAID aura maintenant comme consigne de fonctionner entre 50Mb/s et 200Mb/s (ou ce que vous lui aurez indiqué).

  1. Augmenter la valeur du « Read-Ahead »

Par défaut, votre système va mettre en cache une certaine quantité de donnée lors de la lecture du disque (128Ko de base en général).

Lors de l’accès à de gros fichier plus cette quantité de données sera faible et plus le nombre d’accès disque sera important et inversement plus cette valeur sera élevé et plus le temps d’accès risque d’être impacté pour l’accès au petit fichier.

Le but est de régler cette valeur de manière cohérente pour améliorer les performances générales.

Pour connaître la valeur actuelle de vos raid, utilisez la commande suivante :

blockdev --report | grep /dev/md

Vous récupérez des informations sur vos RAID avec les informations suivantes :

– Etat de lecture/écriture du RAID,
– Nb de secteurs attribués au Read-Ahead,
– Taille de ces mêmes secteurs,
– Tailles des blocs du disque,
– Secteur de démarrage,
– Taille du périphérique,
– nom du périphérique.

Ce qui, dans mon cas, me retourne ceci :

rw  4096   512  1024          0      1020264448   /dev/md0
rw  4096   512  4096          0   1999113289728   /dev/md1

J’ai donc 2 grappes RAID avec chacune un « Read-Ahead » de 2Mo (4096 * 512 octets ), la 3 éme valeur correspondant à la taille des blocs.

Nous allons augmenter cette valeur pour la porter à 32Mo (65536 * 512 octets), ce qui devrait permettre d’accélérer sensiblement le fonctionnement du RAID en un peu limitant les accès disques :

sudo blockdev --setra 65536 /dev/md0
sudo blockdev --setra 65536 /dev/md1

Voila, votre RAID mettra maintenant 32Mo de données en cache avant d’effectuer une nouvelle lecture.

Bon, et après un redémarrage? je refais la manip?

Eh bien non, une petite règle Udev et c’est bon (attention, cette fois-ci il faut indiquer la taille en Ko et pas en blocs):

sudo cat >/etc/udev/rules.d/10-md-read-ahead.rules << EOL
SUBSYSTEM=="block", KERNEL=="md*", ACTION=="change", TEST=="queue/read_ahead_kb", ATTR{queue/read_ahead_kb}="32768"
EOL
  1. Augmenter la taille de cache des chunck ou « Stripe-Cache-Size » (Uniquement RAID 5 ou 6)

Pour celui la j’ai eu un peu plus de mal à comprendre la signification exacte. Le Strip-Size correspondrait à la taille du bloc de données ou chunck ou Stripe complet répartie sur les disques de la grappe RAID.

Attention toutefois, cette option consomme de la RAM  et je n’ai pas su trouver si les disques de spare sont compris dans le calcul de la RAM consommé.

Le calcul suivant permet de déterminer la quantité de RAM attribuée pour chaque grappe RAID :

memoire_consomée = system_page_size(ko) * nb_disque * stripe_cache_size

Pour connaître le system_page_size, il vous suffit de faire :

getconf PAGE_SIZE

Ce qui retourne généralement 4096 octets ou 4Ko.

Dans mon cas, avec une valeur fixée à 16Mb, on obtient tout de même 256Mb par grappe, soit un total de 512Mb de RAM pour cette mise en cache (oui, ça monte vite).

Pour fixer cette valeur, rien de plus simple :

echo 16384 | sudo tee /sys/block/md0/md/stripe_cache_size
echo 16384 | sudo tee /sys/block/md1/md/stripe_cache_size

Et pour rendre cette valeur permanente, il suffit de créer une règle Udev qui fixera la valeur à chaque redémarrage :

sudo cat >/etc/udev/rules.d/10-md-stripe-cache.rules << EOL
SUBSYSTEM=="block", KERNEL=="md*", ACTION=="change", TEST=="md/stripe_cache_size", ATTR{md/stripe_cache_size}="16384"
EOL
  1. Désactiver la gestion de file d’attente SATA (ou Native Command Queuing)

Avant dernière étape, désactiver la gestion de la file d’attente au niveau des disques durs en eux mêmes.

Sur beaucoup de site, vous trouverez le script suivant pour désactiver cette fonction :

for i in sd[abcd]
do
  echo 1 > /sys/block/$i/device/queue_depth
done

En considérant 4 disques durs (sda, sdb, sdc et sdd)sur votre installation.

Si vous obtenez un message d’erreur permission denied, il y’a de grandes chances que le pilote sata de votre carte mère ne supporte pas la file d’attente (par exemple le module sata_nv avant le nForce4).

C’est un bon script, mais quand vous redémarrerez tout sera perdu.

Pour garder cette modification, encore une petite régle Udev et le tour est joué :

sudo cat >/etc/udev/rules.d/05-sd-disable-ncq.rules << EOL
SUBSYSTEM=="block", KERNEL=="sd*", ACTION=="change", TEST=="device/queue_depth", ATTR{device/queue_depth}="1"
EOL
  1. Activer le Bitmap RAID

On n’y est presque,  voici la dernière modification à effectuer. Sur beaucoup de tuto, j’ai put voir qu’ils conseillais d’activer le bitmap avant la synchronisation et de le retirer après. Ok, je veux bien, mais je ne dors pas devant mon serveur…

Alors pour l’activer avant et après, voici ce qu’il faut faire (exemple pris pour md0 mais à adapter à vos besoins) :

#Activer le bitmap
sudo mdadm --grow --bitmap=internal /dev/md0
#Désactiver le bitmap
sudo mdadm --grow --bitmap=none /dev/md0

Edit du 02 Août 2015 :

En raison d’un mauvaise compréhension de ma part concernant le bitmap, la manipulation que j’avais fourni concernant le fichier de configuration du RAID empêche même le démarrage des grappes RAID.

Une fois le bitmap interne activé, il est permanent, nul besoin de le spécifier dans le fichier de configuration, au contraire.

Si vous rencontrez ce problème, voici les lignes de commande pour vous en sortir (une fois arrivé sur le shell intiramfs):

vi /etc/mdadm/mdadm.conf

et supprimer tous les « bitmap=internal » que vous verrez puis enregistrer votre fichier.

Ensuite, pour chaque grappe RAID :

mdadm --assemble /dev/mdX

où « X » est le numéro de votre grappe.

Une fois ceci fait, et seulement si vous utilisez LVM, lancez la commande suivante pour reconnaître vos volumes LVM :

vgchange -a y

puis quittez la console initramfs :

exit

Votre système devrait alors démarrer.

Il ne vous reste plus qu’à reproduire la modification sur le fichier de configuration de mdadm (la modification précédente ne concernait que le fichier contenu dans votre initramfs et était donc volatile) ; n’oubliez pas de mettre à jour votre initramfs pour rendre la modification permanente :

sudo update-initramfs -u

Personnellement, je ne pense pas que cela soit gênant que le bitmap soit activer en permanence et comme je ne vais pas le réactiver à chaque démarrage (moins d’une fois par an je n’y penserai sûrement pas la prochaine fois….).

Pour rendre cette modification permanente à chaque redémarrage, éditez votre fichier de configuration mdadm :

sudo nano /etc/mdadm/mdadm.conf

Et pour chaque ARRAY où vous souhaitez activer le bitmap, ajoutez le paramètre suivant à la ligne :

bitmap=internal

Exemple :

ARRAY /dev/md/0 metadata=1.2 UUID=f2ba6d0b:d6e53695:6ecde882:130b0030

Devient :

ARRAY /dev/md/0 metadata=1.2 UUID=f2ba6d0b:d6e53695:6ecde882:130b0030 bitmap=internal

Et comme votre initramfs détient sa propre copie de mdadm.conf, il ne reste plus qu’à le mettre à jour avec :

sudo update-initramfs -u

Et voilà, tout est bon et au prochain démarrage tout sera configuré aux petits oignons sans rien faire.

 

Astuce :

pour forcer udev à prendre en compte les changement et vérifier qu’il n’y ait pas d’erreur : 

udevadm control --reload-rules

Et si vous voulez vérifiez que les règles udev fonctionnent pour un périphériques RAID :

udevadm test --action=change /sys/block/mdX

Où X est le numéro de l’Array.

Au passage ça appliquera les changements que l’on vient de faire.

 

Edit du 12/06/2015 :

Juste un petit retour sur les modifications effectuées, avant l’optimisation du RAID, la synchronisation prenait jusqu’à 3jours (oui, c’est énorme et il n’y a qu’1.8To de données). Suite à cette optimisation, la synchronisation prend moins de 6heures :

Jun  7 00:57:01 SERVER /USR/SBIN/CRON[13793]: (root) CMD (if [ -x /usr/share/mdadm/checkarray ] && [ $(date +%d) -le 7 ];
	 then /usr/share/mdadm/checkarray --cron --all --idle --quiet; fi)
Jun  7 00:57:01 SERVER mdadm[7633]: RebuildStarted event detected on md device /dev/md/0
Jun  7 00:57:24 SERVER mdadm[7633]: RebuildStarted event detected on md device /dev/md/1
Jun  7 00:57:24 SERVER mdadm[7633]: RebuildFinished event detected on md device /dev/md/0
Jun  7 01:47:25 SERVER mdadm[7633]: Rebuild22 event detected on md device /dev/md/1
Jun  7 02:37:25 SERVER mdadm[7633]: Rebuild44 event detected on md device /dev/md/1
Jun  7 03:27:25 SERVER mdadm[7633]: Rebuild63 event detected on md device /dev/md/1
Jun  7 04:17:26 SERVER mdadm[7633]: Rebuild80 event detected on md device /dev/md/1
Jun  7 05:24:53 SERVER mdadm[7633]: RebuildFinished event detected on md device /dev/md/1

 

Gawindx
Gawindx

Gawindx

Passionné de l'outil informatique dès mon plus jeune âge (j'ai commencé sur un MO5), je mets mes compétences au service de la communauté. Je "flirte" avec Linux depuis 2005 et j'ai complétement basculé dans le libre depuis plus de 3 ans.