Linux - Réglage du contrôleur RAID matériel réel (scsi et cciss)

29

La plupart des systèmes Linux que je gère disposent de contrôleurs RAID matériels (principalement HP Smart Array ). Ils exécutent tous RHEL ou CentOS.

Je recherche des paramètres ajustables du monde réel pour aider à optimiser les performances des configurations qui intègrent des contrôleurs RAID matériels avec des disques SAS (Smart Array, Perc, LSI, etc.) et un cache sauvegardé par batterie ou flash. Supposons RAID 1 + 0 et plusieurs broches (4+ disques).

Je passe beaucoup de temps à régler les paramètres du réseau Linux pour les applications de trading à faible latence et financières. Mais bon nombre de ces options sont bien documentées (modification des tampons d'envoi / réception, modification des paramètres de la fenêtre TCP, etc.). Que font les ingénieurs côté stockage?

Historiquement, j'ai apporté des modifications à l' ascenseur de planification d'E / S , en optant récemment pour les planificateurs deadlineet nooppour améliorer les performances de mes applications. Au fur et à mesure que les versions de RHEL ont progressé, j'ai également remarqué que les valeurs par défaut compilées pour les périphériques de bloc SCSI et CCISS ont également changé. Cela a eu un impact sur les paramètres de sous-système de stockage recommandés au fil du temps. Cependant, cela fait un moment que je n'ai vu aucune recommandation claire. Et je sais que les valeurs par défaut du système d'exploitation ne sont pas optimales. Par exemple, il semble que le tampon de lecture anticipée par défaut de 128 Ko soit extrêmement petit pour un déploiement sur du matériel de classe serveur.

Les articles suivants explorent l'impact sur les performances de la modification du cache de lecture anticipée et des valeurs nr_requests sur les files d'attente de blocs.

http://zackreed.me/articles/54-hp-smart-array-p410-controller-tuning
http://www.overclock.net/t/515068/tuning-a-hp-smart-array-p400-with -linux-pourquoi-le-réglage-vraiment-important
http://yoshinorimatsunobu.blogspot.com/2009/04/linux-io-scheduler-queue-size-and.html

Par exemple, ce sont des modifications suggérées pour un contrôleur RAID HP Smart Array:

echo "noop" > /sys/block/cciss\!c0d0/queue/scheduler 
blockdev --setra 65536 /dev/cciss/c0d0
echo 512 > /sys/block/cciss\!c0d0/queue/nr_requests
echo 2048 > /sys/block/cciss\!c0d0/queue/read_ahead_kb

Quoi d'autre peut être réglé de manière fiable pour améliorer les performances de stockage?
Je recherche spécifiquement les options sysctl et sysfs dans les scénarios de production.

ewwhite
la source

Réponses:

38

J'ai constaté que lorsque j'ai dû régler pour une latence plus faible par rapport au débit, j'ai réduit nr_requests par rapport à sa valeur par défaut (jusqu'à 32). L'idée de lots plus petits équivaut à une latence plus faible.

Aussi pour read_ahead_kb, j'ai constaté que pour les lectures / écritures séquentielles, l'augmentation de cette valeur offre un meilleur débit, mais j'ai trouvé que cette option dépend vraiment de votre charge de travail et de votre modèle d'E / S. Par exemple, sur un système de base de données que j'ai récemment réglé, j'ai modifié cette valeur pour qu'elle corresponde à une taille de page db unique, ce qui a contribué à réduire la latence de lecture. Augmenter ou diminuer au-delà de cette valeur s'est avéré nuire aux performances dans mon cas.

En ce qui concerne les autres options ou paramètres pour les files d'attente de périphériques bloqués:

max_sectors_kb = J'ai défini cette valeur pour qu'elle corresponde à ce que le matériel autorise pour un seul transfert (vérifiez la valeur du fichier max_hw_sectors_kb (RO) dans sysfs pour voir ce qui est autorisé)

nomerges = cela vous permet de désactiver ou d'ajuster la logique de recherche pour la fusion des requêtes io. (désactiver cette option peut vous faire économiser des cycles de processeur, mais je n'ai vu aucun avantage à changer cela pour mes systèmes, donc je l'ai laissé par défaut)

rq_affinity = Je n'ai pas encore essayé cela, mais voici l'explication derrière cela à partir des documents du noyau

Si cette option est '1', la couche de bloc migre les demandes complétées vers le "groupe" de processeurs qui a initialement soumis la demande. Pour certaines charges de travail, cela permet une réduction significative des cycles du processeur en raison des effets de mise en cache.
Pour les configurations de stockage qui doivent maximiser la distribution du traitement d'achèvement, le fait de définir cette option sur "2" force l'exécution à l'exécution sur le processeur demandeur (en contournant la logique d'agrégation "groupe") "

scheduler = vous avez dit que vous avez essayé l'échéance et noop. J'ai testé à la fois noop et date limite, mais j'ai trouvé la date limite gagnante pour les tests que j'ai faits le plus récemment pour un serveur de base de données.

NOOP a bien fonctionné, mais pour notre serveur de base de données, j'ai pu obtenir de meilleures performances en ajustant le planificateur de délais.

Options pour le planificateur de délais situé sous / sys / block / {sd, cciss, dm -} * / queue / iosched /:

fifo_batch = un peu comme nr_requests, mais spécifique au planificateur. La règle de base est de réduire cela pour une latence plus faible ou pour le débit. Contrôle la taille du lot des demandes de lecture et d'écriture.

write_expire = définit le délai d'expiration pour les lots d'écriture par défaut est 5000 ms. Une fois de plus, cette valeur diminue votre latence d'écriture tandis que l'augmentation de la valeur augmente le débit.

read_expire = définit le délai d'expiration pour les lots de lecture par défaut est 500 ms. Les mêmes règles s'appliquent ici.

front_merges = J'ai tendance à désactiver cette option et elle est activée par défaut. Je ne vois pas la nécessité pour le planificateur de gaspiller les cycles de processeur en essayant de fusionner les demandes d'E / S.

writes_starved = puisque le délai est orienté vers les lectures, la valeur par défaut ici est de traiter 2 lots de lecture avant de traiter un lot d'écriture. J'ai trouvé que la valeur par défaut de 2 convenait à ma charge de travail.

rtorti19
la source
7
... et c'est ainsi que vous publiez votre première réponse sur un site. Bien joué!
Jeff Ferland
1
C'est un bon début et l'exécution de tests répétés dans des conditions contrôlées m'a aidé à modifier un peu les performances de l'application. Il est également utile de voir comment je peux régler le stockage pour les tendances générales de la charge de travail.
ewwhite
4

Plus que tout, tout dépend de votre charge de travail.

read_ahead_kbpeut vous aider s'il est vraiment utile de lire de nombreuses données d'un fichier à l'avance, comme lors de la diffusion vidéo. Parfois, cela peut vous blesser gravement. Oui, les 128 Ko par défaut peuvent sembler petits, mais avec suffisamment de simultanéité, ils commencent à sembler gros! D'un autre côté, avec un serveur tel qu'un serveur d'encodage vidéo qui ne convertit que les vidéos d'un format à un autre, cela pourrait être une très bonne idée de régler.

nr_requests, une fois accordé, peut facilement inonder votre contrôleur RAID, ce qui nuit encore aux performances.

Dans le monde réel, vous devez surveiller les latences . Si vous êtes connecté au réseau SAN, jetez un œil à ce que vous souhaitez utiliser iostat, sarou vérifiez ce que vous voulez, et voyez si les délais de service des demandes d'E / S ont dépassé le plafond. Bien sûr, cela aide également les disques locaux: si les latences sont très très importantes, envisagez de réduire vos paramètres d'ascenseur d'E / S en rétrogradant max_requests et d'autres paramètres.

Janne Pikkarainen
la source
Quels autres paramètres?
ewwhite
4

Pour info read_ahead_kbet blockdev --setrasont juste des façons différentes de définir le même paramètre en utilisant différentes unités (kB vs secteurs):

foo:~# blockdev --setra 65536 /dev/cciss/c0d0
foo:~# blockdev --getra /dev/cciss/c0d0
65536
foo:~# cat /sys/block/cciss\!c0d0/queue/read_ahead_kb
32768
foo:~# echo 2048 > /sys/block/cciss\!c0d0/queue/read_ahead_kb
foo:~# cat /sys/block/cciss\!c0d0/queue/read_ahead_kb
2048
foo:~# blockdev --getra /dev/cciss/c0d0
4096

Alors le

blockdev --setra 65536 /dev/cciss/c0d0

dans votre exemple n'a aucun effet.

ntherning
la source