Deepdive – VMware ESXi I/O Scheduler & Queue Depth.

Deepdive – VMware ESXi I/O Scheduler & Queue Depth.

La Queue Depth, une histoire de SAN et de protocole d’accès en mode bloc.

Les entreprises se sont souvent équipées de baies SAN (Storage Area Network). Ce stockage avec accès en mode bloc est souvent utilisé avec des applications transactionnelles, bases de données, messagerie ou autres.

Les baies SAN utilisent des protocoles d’accès comme le Fibre Channel ou iSCSI et partagent leur volumétrie sous forme de volumes logiques (LUN). Ces LUNs sont utilisables comme des disques locaux par les serveurs et accessibles en mode bloc.

Les baies NAS mettent quant à elles leur capacité disponible à disposition des serveurs sous la forme d’un partage réseau accessible via un protocole de partage de fichiers en réseau comme NFS ou CIFS (le protocole de partage de fichiers en réseau de Windows aussi connu sous le nom SMB).

Dans une infrastructure virtualisée, on estime à plus de 80% les problèmes causés par le stockage. L’un des points majeur à surveiller avec du stockage en mode bloc et ce qu’on appel la profondeur de la file d’attente « queue depth ». De nos jours, les baies SAN sont plus intelligentes et capables de prendre en charge de nombreuses actions réalisées dans le passé par la couche de virtualisation. Bien que les éditeurs de solution de virtualisation et constructeurs de baie SAN aient fait un énorme travail sur le développement d’API et des nombreuses primitives permettant de rendre les baies de stockage plus intelligentes en leur délégant de nombreuses tâches. Sur des environnements conséquents, il n’en reste pas moins que le problème des files d’attentes (Queue Depth) et lié aux protocoles d’accès utilisé pour accéder à la donnée.

La Queue Depth et VMware Esxi :

Sur le principe du stockage en mode bloc, des volumes logiques (LUN) vont être présentés à l’hyperviseur. Ce dernier va gérer une file d’attente (Queue Depth) par volume logique (LUN). Lorsqu’une instruction (I/O) arrive, aussi bien une lecture qu’une écriture, cette instruction va être placée dans cette file d’attente pour être traitée.

Pour traiter l’information reçue dans la file d’attente, l’hyperviseur va récupérer l’action qui est au-dessus de la file d’attente depuis le plus longtemps (principe du FIFO, First In First Out) et l’envoyer au contrôleur de la baie de stockage. Cette dernière va traiter l’information reçue et répondre à la demande de la machine virtuelle.

Cette file d’attente dispose d’un nombre de slot limité, la plupart du temps, 32, 64, 128, rarement au-dessus, mais c’est possible. Cette valeur va dépendre en grande partie de l’adaptateur de stockage présent dans l’hyperviseur (Carte Physique HBA ou carte réseau + initiateur software) traitant les I/O, des paramètres avancés configurés dans le module (VMkernel Module driver) de la carte et des mécanisme de vSphère DSNRO ou SIOC.

Il faut prendre en compte que la baie de stockage, dispose elle aussi d’une file d’attente (environ 2048 sur les baies de milieu de gamme). Sur la file d’attente de la baie, ce n’est plus un seul hyperviseur mais plusieurs qui envoient des commandes I/O.

La complexité de la queue depth, vient du fait qu’elle peut être configurée en différents points de la trajectoire d’un IO. Dans la couche VMFS (DSNRO), dans un module noyau (couche driver de la carte chargée dans le vmkernel), dans la couche matérielle de l’initiateur HBA (serveur hôte – HBA BIOS), à la destination (Ports des contrôleurs de la baie SAN), sur la couche OS invité dans la VM (Virtual Machine et son contrôleur vSCSI) et parfois même dans directement codé dans l’application. A cela, vient s’ajouter des valeurs limites imposées par une multitude d’équipements comme le backend des baies de stockage, la queue des disques physiques, le buffer d’entrée et sortie des switchs, etc …

Ci-dessous un tableau des valeurs de queue depth sur les différentes couches:

Couches Valeur de QD
Application dépend de l’application
Virtual vSCSI Card Driver default = 32
Couche VMFS (DSNRO) default = 32
HBA VMkernel Module Driver *
default = 64
HBA Bios **
default = varie en fonction du modèle de carte (entre 512 et 3072 par port)
Target Port SAN dépend du nombre et du modèle de port sur les contrôleurs de la baie (entre 512 et 2048 par port)

Les valeurs de Queue Depth de l’adaptateur de stockage (HBA)** et de la LUN* peuvent être analysées via l’outil ESXTOP en ligne de commande: (VMware KB 1027901)

Schéma du parcours d’un I/O :


Que se passe-t-il lorsque ces files d’attentes (Queue Depth) sont pleines ?

Nous voyons dans le schéma précédent que les connexions arrivent sur des ports de la baie. Un port ne peut desservir qu’une seule demande d’I/O à la fois. Les demandes supplémentaires sont placées dans une file d’attente et si les ports du contrôleur reçoivent plus de 2048 demandes d’IO au même moment, la file d’attente est inondée (statut QFULL) et le contrôleur demande à l’hôte de suspendre les nouvelles demandes jusqu’à ce que la file d’attente devienne disponible.

L’ESXi, va recevoir une commande d’étranglement afin de diminuer la file d’attente de la LUN à une valeur plus faible (minimum 1).

Ensuite, le VMkernel va vérifier toutes les 2 secondes si la condition QFULL est résolue et augmentera lentement la file d’attente LUN à sa valeur normale (cela peut prendre jusqu’à 60s)

Comment se comporte les machines virtuelles en cas de Queue FULL ?

C’est simple, la ou les commandes ne seront pas traitée(s) dans l’immédiat. La condition de QFULL est prise en charge par le VMkernel Module Driver de la carte HBA. Le statut QFULL n’est pas retourné directement à l’OS. Certains périphériques de stockage retournent BUSY plutôt que QFULL et enregistrent les erreurs BUSY dans /var/log/vmkernel. Il convient d’analyser les senses codes iscsi dans les logs pour déterminer le type d’erreur.

Une commande est envoyée à la VM, qui va déclencher un I/O Wait puis, une réémission de la commande, et ce jusqu’à un certain timeout souvent réglé par défaut à 60s et réglable dans le système d’exploitation.

En fonction du système d’exploitation un I/O timeout va provoquer différents comportements suivant le système d’exploitation et le système de fichier. Cela peut être un simple « freeze » de la VM (Windows) ou un passage en « read only » du système de fichier (Linux).

Il devient donc évident que moins le nombre de VMs par LUN est élevé, moins nous avons de risques de rencontrer ces problèmes. Les best practices conseil de ne pas dépasser un certain nombre de VMs par LUN (en général entre 10 et 15 VMs). Évidemment, plus les VMs génèrent d’I/O et donc de forte charge en lecture et écriture, moins il faut de VM par LUN.

Comme nous l’avons abordé en début de ce post, l’intérêt des protocoles de type file (NFS, CIFS) est de ne pas avoir ce mode de gestion d’I/O et donc d’éliminer cette complexité de gestion. En effet, il n’y a pas de principe de file d’attente par LUN, mais plutôt par fichier. De même pour les solutions hyperconvergées actuelles dites « Scale-Out »,
basées sur du stockage local (SATA, SSD, RAM) permettant une distribution des I/O sur l’ensemble des nœuds et ainsi une réduction de l’impact de la queue depth.

Comment calcule-t-on la profondeur des files d’attentes ?

La profondeur de la file d’attente est calculée par la formule suivante :

T => (P * Q * L)

T = Target Port Queue Depth de la baie (2048)

P = Nombre de chemin actif connecté au port de la baie

Q = Queue Depth

L = Nombre de LUN présenté à l’hôte via ce port

Nous sommes d’accord que la file d’attente est le nombre de demandes d’I/O (commandes SCSI) qui peuvent être mis en attente à un moment donné sur un contrôleur de stockage. Chaque demande d’I/O depuis un initiateur HBA d’un hôte vers le contrôleur de stockage consomme une entrée en file d’attente. Quand la file d’attente atteint sa valeur maximale, le contrôleur rejette les commandes entrantes en renvoyant une réponse QFULL (file d’attente pleine).

Malgré qu’une baie puisse avoir 2 ou 4 ports par contrôleur, un seul hyperviseur (ESXi) n’utilise qu’un seul des chemins actif pour l’envoi d’un I/O. De ce fait, lors du calcul de la file d’attente, vous utilisez uniquement un seul chemin actif vers l’un des ports d’un contrôleur de la baie. C’est pour cette raison que la valeur de « P » dans le calcul est de « 1 ».

De plus, chaque port d’un contrôleur ne possède pas forcement une file d’attente de 2048. La valeur maximale de la file d’attente par port peut varier en fonction du modèle de la baie de stockage (entre 256 et 2048).

Le « Target Port Queue Depth » dans le calcul représente la « max-queue-depth » au niveau du contrôleur de la baie et non la « max-queue-depth » par port. Bien souvent, sur les baies on retrouve une « max-queue-depth » de 512 à 2048 par port. (exemple: 4 ports x 512 = 2048 ou 4 ports x 2048 = 8192)

Dans le cas d’un seul hyperviseur:

  • Prenons l’exemple d’un ESXi, connectés à 15 LUN (L) présentées par une baie actif/passif ayant 4 ports par contrôleur (target port) avec un chemin actif (P) (active path) et chaque port de la baie une valeur max-queue-depth de 512 (4 ports x 512 = 2048).

T ≥ (P * Q * L)

T ≥ (1 x Q x 15)

2048 ≥ (1 x Q x 15)

Q = 2048 / 1 x 15

Q = 136,5

L’intérêt pour nous n’est pas tellement de calculer la valeur de (Q) par LUN, elle est bien souvent à 32 à cause de DSNRO (sauf dans le cas d’une modification manuelle), mais plutôt d’estimer les limites à ne pas dépasser pour éviter une saturation des Queues.

  • Prenons l’exemple d’un ESXi, connectés à 15 LUN (L) avec une Queue Depth de 32 par LUN présentées par une baie actif/passif ayant 4 ports par contrôleur (target port) avec un chemin actif (P) (active path) et chaque port de la baie une valeur max-queue-depth de 2048 (4 ports x 2048 = 8192).

T ≥ ESXi1 (P * Q * L)

T ≥ ESXi1 (1 * 32 * 15)

8192 ≥ (1 * 32 * 15)

8192 ≥ 480 (true)

Conclusion: Cette configuration, est loin de saturer la baie de stockage (QFULL), ni la carte HBA de l’hyperviseur.

  •  Prenons l’exemple d’un ESXi, connectés à 100 LUN (L) avec une Queue Depth de 32 par LUN présentées par une baie actif/passif ayant 4 ports par contrôleur (target port) avec un chemin actif (P) (active path) et chaque port de la baie une valeur max-queue-depth de 2048 (4 ports x 512 = 2048).

T ≥ ESXi1 (P * Q * L)

T ≥ ESXi1 (1 * 32 * 100)

2048 ≥ (1 * 32 * 100)

2048 ≥ 3200 (false)

Conclusion: En cas de très forte activité I/O des VMs, cette configuration est capable de saturer la baie de stockage (QFULL), obliger l’hyperviseur à diminuer les queue depth (Q) par LUN et aussi saturer la carte HBA de l’hôte. (pour info, la limite max queue depth par port d’une carte HBA peut aller de 512 (1Gbps) à 3072 (16Gbps))

Dans le cas de multiples hyperviseurs:

  • Prenons l’exemple de 10 ESXi, connectés à 15 LUN (L) avec une Queue Depth de 32 par LUN présentées par une baie actif/passif ayant 4 ports par contrôleur (target port) avec un chemin actif (P) (active path) et chaque port de la baie une valeur max-queue-depth de 2048 (4 ports x 2048 = 8192).

T ≥ ESXi1 (P * Q * L) + ESXi2 (P * Q * L) + … + ESXin (P * L * Q)

T ≥ ESXi1 (1 * 32 * 15) + ESXi2 (1 * 32 * 15) + … + ESXin (1 * 32 * 15)

8192 ≥ (1 * 32 * 15) x 10

8192 ≥ 4800 (true)

Conclusion: Cette configuration, ne permet pas de saturer la baie de stockage (QFULL).

  • Prenons l’exemple de 10 ESXi, connectés à 15 LUN (L) avec une Queue Depth de 32 par LUN présentées par une baie actif/passif ayant 4 ports par contrôleur (target port) avec un chemin actif (P) (active path) et chaque port de la baie une valeur max-queue-depth de 512 (4 ports x 512 = 2048).

T ≥ ESXi1 (P * Q * L) + ESXi2 (P * Q * L) + … + ESXin (P * L * Q)

T ≥ ESXi1 (1 * 32 * 15) + ESXi2 (1 * 32 * 15) + … + ESXin (1 * 32 * 15)

2048 ≥ (1 * 32 * 15) x 10

2048 ≥ 4800 (false)

Conclusion: En cas de très forte activité I/O des VMs, cette configuration est capable de saturer la baie de stockage (QFULL) et obliger les hyperviseurs à diminuer leurs queues depth (Q) par LUN.

L’hyperviseur ESXi et DSNRO (Disk Scheduler Number Request Outstanding)

Nous allons tout au long de ce post apprendre comment l’hyperviseur de VMware ESXi parvient à gérer correctement les nombreux I/O qu’il reçoit et ce grâce au scheduler d’I/O (DSNRO) du VMKernel.

Voici un excellent schéma trouvé sur le blog de notre amis Vladan représentant tout les mécanismes entrants en jeu dans le réglage de la Queue Depth.


DSNRO est uniquement utilisé quand deux ou plusieurs machines virtuelles partagent un même volume (LUN « Logical Unit Number ») et ne s’active pas si une seule machine virtuelle est présente sur une LUN.  DSNRO n’est pas utilisé non plus lorsque le SIOC est activé et dans ce cas c’est la queue depth du VMkernel Module Driver de la HBA qui est prise en compte pour la queue depth des LUNs (DQLEN).

Avant la version 5.5 de VMware Esxi, il était possible d’agir sur la valeur de la file d’attente (Queue Depth) Disk.SchedNumReqOutstanding (DSNRO) et la régler
par hôte. Depuis la version 5.5 de VMware ESXi, il n’est plus possible de modifier la valeur globale par hôte mais uniquement par LUN. Par contre, DSNRO doit être fixé par (LUN) sur tous les hôtes ESXi.

Ci-dessous un tableau des valeurs de Queue depth par défaut configurées dans le VMkernel Module Driver d’une carte QLOGIC sur différentes versions d’ESXi :

ESXi/ESX version Queue depth
3.5 with driver version 6.04 16
3.5 with driver version 6.07 & 7.x 32
4.0 32
4.1 32
5.0 64
5.1 64
5.5 64
6.0 64

Comment fonctionne ce paramètre avancé du VMkernel Disk.SchedNumReqOutstanding (DSNRO) ?

DSNRO agit au niveau du noyau de l’hyperviseur sur la couche VMFS. DSNRO représente simplement le nombre maximum d’I/O (Input / Output) que toutes les VMs d’une même LUN peuvent délivrer au sein d’un même hyperviseur. Il fixe ainsi une limite maximum de commande I/O actives acceptées par le VMkernel de l’hôte pour une LUN à un instant T et ce pendant une certaine durée.

Quand une VM est seule sur une LUN, elle a la possibilité de remplir la valeur maximale de la file d’attente de la carte physique (HBA) ou (Network Card + Software initiator) défini dans les paramètres du driver (VMkernel Module Driver). Par contre, quand la VM partage la LUN avec d’autre VMs actives et générant des I/O, la valeur de DSNRO va permettre « d’étrangler » le nombre d’I/O afin de favoriser l’équité entre les VMs d’un même hôte et d’une même LUN.

Comme nous l’avons vu précédemment, chaque hôte dispose de sa propre profondeur de file d’attente indépendante par LUN et chaque VM partagera de façon égale la profondeur de file d’attente (en supposant que chaque machine virtuelle réalise des actions identiques d’un point de vue du stockage).

Exemple :

Avec DSNRO

Si nous configurons Disk.SchedNumReqOutstanding à une valeur par défaut de 64 IO actifs et que nous lançons un workload IOMeter sur trois VMs pour générer 64 I/O (64 x 3 = 192 I/O). On constate via les compteurs de la commande « esxtop + touche u » environ 64 dans le compteur ACTV (I/O actif) et les 128 autres I/O dans le compteur QUED.

Sans DSNRO

Dans le cas d’une Queue Depth de 64 configurée sur une carte HBA et une seule VM générant des I/O vers un datastore VMFS. Les 64 I/O seraient directement transmis au driver de la carte HBA ou driver du software initiator iscsi « iscsi_vmk ».

De nos jours, dans la plupart des environnements, une LUN est partagée par plusieurs machines virtuelles et dans la plupart des cas, ces machines virtuelles génèrent des IO et doivent être traitées également.

Workflow des traitements I/O dans le VMkernel :


Le rôle de DSNRO et de favoriser l’équité des VMs lorsque le VMkernel détecte que le seuil d’un certain compteur est atteint.

Le nom de ce compteur est Disk.SchedQControlVMSwitches. Ce paramètre est utilisé pour déterminer quand limiter le nombre d’I/O envoyé à la file d’attente du driver afin de permettre à toutes les VMs de planifier l’envoi de leurs I/O. Il permet de conserver un équilibre entre équité et performance.

Par défaut, ce compteur est réglé à une valeur de 6, ce qui signifie que le VMkernel devra détecter 6 fois que l’I/O en cours de traitement ne vient pas de la même VM que l’I/O traité précédemment avant qu’il ne règle la valeur de la file d’attente « Queue Depth » à la valeur spécifiée dans Disk.SchedNumReqOutstanding (par défaut = 32)

La raison de cette limitation de la Queue Depth est du au fait que le VMkernel n’est pas capable de contrôler l’ordre des commandes émises par le VMkernel Module Driver.

Que se passerait-il si il n’existait pas de moyen de limiter la Queue Depth ?

Prenons un exemple :

  • Une VM A émettant beaucoup d’IO
  • Une VM B éméttant quelques IO

La VM A utiliserait tout le temps une plus grande partie de la Queue Depth.

Chaque fois que la VM B emmétrait un IO, il serait récupéré à un moment donné par le scheduler d’I/O du VMkernel selon le principe du FIFO et envoyé au driver avant même qu’un autre IO de la VM B puisse commencer à être traité par le VMkernel. A chaque envoi d’I/O de la VM B, il faudrait passer derrière les 64 autres I/O présents dans la queue du driver ce qui provoquerait des latences, des I/O Wait, des réémissions d’I/O voir des Timeout.

En limitant le nombre de demande d’IO en suspens (queue depth), nous permettons au VMkernel de scheduler les IO de la VM B bien plus tôt dans le courant d’IO de la VM A et ainsi nous réduisons la pénalité de latence pour la VM B.

Mais alors, faut-il mettre la valeur de Disk.SchedNumReqOutstanding à la même valeur que la Queue Depth du driver de la carte ?

  • Si vous souhaitez que vos I/O soient traités aussi rapidement que possible sans aucune équité, OUI !
  • Si vous mélangez des VMs avec des workloads différents sur un seul datastore et ne voulez pas avoir des temps de latence excessif car certaines VMs provoquent beaucoup d’I/O, NON !

Comment sont traités les I/Os séquentiels dans le cas de Disk.SchedNumReqOutstanding?

Quand plusieurs VMs partagent la même LUN, il arrive qu’on veuille émettre plus d’I/O que ce qui est défini dans le paramètre Disk.SchedNumReqOutstanding.

Par exemple, dans le cas d’un envoi d’I/O séquentiel, nous pouvons autoriser à un certain nombre d’I/O supplémentaire a être traité.

La encore, VMware a pensé à tout ! Un contrôle permettant de faire la différence entre un I/O séquentiel et aléatoire. Ce contrôle est effectué par Disk.SectorMaxDiff. En fonction du résultat retourné par ce paramètre Disk.SectorMaxDiff, on fait appel à Disk.SchedQuantum qui va autoriser une VM pendant une opération séquentielle à émettre des I/O additionnels consécutifs pour chaque cycle de Disk.SchedNumReqOutstanding.

Il semblerait peut être plus juste en terme d’équité de traiter l’I/O d’une autre VM mais ce mécanisme a été pensé dans le but d’éviter de détruire le séquentiellement d’un workload. Le VMKernel est capable de différencier et analyser les I/O produits dans une plage de secteurs disques en vérifiant la proximité entre le secteur de l’I/O précédemment traité et le suivant. L’I/O est considéré comme séquentiel, si il est à moins de 2000 secteurs disque de l’I/O précédent. Ce contrôle d’I/O en fonction d’une plage de secteur disque est contrôlé par le paramètre avancé nommé Disk.SectorMaxDiff

Pour en revenir à notre paramètre Disk.SchedQuantum. Par défaut, ce paramètre à une valeur de 8. Ce paramètre représente le nombre maximum d’I/O consécutif séquentiel autorisé à une VM avant de forcer le scheduler d’I/O à traiter une autre VM.

Pour imager mes propos, prenons le cas d’une VM en pleine opération séquentielle. Nous allons autoriser la VM à émettre les I/O autorisés par Disk.SchedNumReqOutstanding plus 8 I/O supplémentaires.

Comment le VMkernel sait-il quand ne plus utiliser Disk.SchedNumReqOutstanding ?

Le VMkernel utilise le paramètre Disk.SchedQControlSeqReqs pour déterminer quand revenir à la valeur de Full Queue Depth I/O et donc sans équité (valeur de Queue Depth du driver de la carte HBA ou de l’initiateur software). Disk.SchedQControlSeqReqs se réfère au nombre de fois que des I/O sont émis depuis la même VM avant de revenir à une valeur de Full Queue Depth.

La valeur par défaut de ce paramètre est de 128. Le VMKernel va détecter si une VM envoie 128 I/O à la suite sans interruption (2 x 64 IO ou 4 x 32 IO en fonction de la valeur de Disk.SchedNumReqOutstanding) et donc sans interruption par le traitement I/O d’une autre VM. Si c’est le cas, DSNRO n’équilibre plus la Queue Depth.

La logique de ce paramètre est que si une VM B émet très peu d’I/O (moins de 1 parmi 128 d’une autre VM sur la même LUN), nous allons laissé subir la pénalité de latence à la VM B, car on suppose qu’il n’y a pas de disque lié à cette VM

  • Si la profondeur de votre file d’attente « Queue Depth » est trop faible, vous pouvez avoir une latence très élevée lorsque vos VMs tentent d’émettre un nombre élevé d’IO en parallèles car ils vont tous en file d’attente à l’intérieur de l’hyperviseur (dans le VMKernel).
  • Si la profondeur de file d’attente « Queue Depth » est trop grande, vous pouvez avoir beaucoup d’IO en queue et surcharger votre baie de stockage.

Tous ça pour montrer l’importance de la Queue Depth dans un environnement virtualisé. Nous aurions pu aller encore plus loin en décortiquant l’infrastructure PSA (Pluggable Storage Architecture), les mécanismes du SIOC (Storage I/O Control) ou le gain apporté par les primitives VAAI … Peut être lors d’un prochain article 😉

twitterlinkedin
Publié dans Stockage, Vmware vSphere
6 commentaires sur “Deepdive – VMware ESXi I/O Scheduler & Queue Depth.
  1. VirtTom dit :

    Salut,

    sympa l’article ! je vais devoir le relire 1 fois pour tout digérer il me semble voir 2…

    En tout cas ça a remis à jour mes connaissances sur le sujet ! même si comme tu le soulignes ce n’est plus la même donne avec l’avènement du NFS / ServerSAN.

    afin d’être tout à fait sur de ce qui est dit ici, les points encore peu clairs à mon sens :

    – DiskSchedQcontrolVMswitches (là clairement je dois réviser mes copies).

    – On traite 1 LUN x VM x 1 ESXi. QUID du cas x LUN par ESXi et donc de la segmentation de la Qdepht de la HBA ? Quid des cartes iSCSI ?

    bon apres vu la longueur de l’article, ça aurait été abusé, à quand le livre ?:)

    virtualement,

    @virttom

    • Philippe LIMA dit :

      Hello Thomas (je t’ai démasqué)

      – On traite 1 LUN x VM x 1 ESXi. QUID du cas x LUN par ESXi
      Oui, 1 LUN avec XX VMs sur 1 ESXi mais dans le cas ou nous avons plusieurs LUN, le principe reste le même.
      A partir du moment ou DiskSchedQcontrolVMswitches détecte 6 commandes I/O provenant de VMs différentes. Il va positionner la valeur de Queue Depth de la LUN à la valeur de Disk.SchedNumReqOutstanding.

      Qdepht de la HBA ?

      La « segmentation » ou plutôt la valeur limite de la QD dans une carte HBA est simplement définie dans le driver chargé dans le VMkernel. En fonction du modèle de carte HBA, elle peut varier.
      Pour agir sur cette valeur, il te suffit de lister les modules (driver) via un « esxcli system module list » et une fois le driver identifié, de passer des paramètres à ton driver via ‘esxcli system module parameters set -p nom_du_paramètre_QD=64 -m nom_du_driver

      Quid des cartes iSCSI ?

      Même principe, sauf que tu utilise ta Network Card pour encapsuler les commandes SCSI dans une trame TCP/IP via l’initiator iscsi software de l’ESXi.
      Pour agir dessus, même principe via la commande ‘esxcli system module parameters set -m iscsi_vmk -p iscsivmk_LunQDepth=value’

      Après HBA ou Software iSCSI, la Queue Depth sera étrangler par DSNRO en cas de 6 switchs de DiskSchedQcontrolVMswitches (plusieurs VMs par LUN) ou tu profitera de la valeur de Full Queue Depth de ton driver de carte HBA ou Software iSCSI (1 VM par LUN)

      à quand le livre ?
      J’ai pas encore assez de temps de libre sur les bras pour cela 😉

      A bientôt et merci pour le commentaire 😉

  2. vBlackCat dit :

    Bonjour,

    J’aimerais savoir pourquoi est ce que dans votre calcul, le fait que la baie ait 4 ports (et pas un seul) ne rentre pas du tout en compte ? Vous divisez bien par 10 le résultat final pour adapter la LUN Queue Depth à la concurrence d’accès de plusieurs ESXi, mais ne faudrait-il pas également le multiplier par 4 puisque la baie à 4 ports avec chacun une file d’attente de 2048 et que rien n’indique que tous les ESXi vont attaquer le même port simultanément ? Au pire si on considère qu’on est en iSCSI et ALUA, cela fait tout de même 2 ports utilisables en même temps pour servir un même LUN non ?

    • Philippe LIMA dit :

      J’aimerais savoir pourquoi est-ce que dans votre calcul, le fait que la baie ait 4 ports (et pas un seul) ne rentre pas du tout en compte ? Vous divisez bien par 10 le résultat final pour adapter la LUN Queue Depth à la concurrence d’accès de plusieurs ESXi, mais ne faudrait-il pas également le multiplier par 4 puisque la baie à 4 ports avec chacun une file d’attente de 2048 et que rien n’indique que tous les ESXi vont attaquer le même port simultanément ?

      Nous sommes d’accord que la file d’attente est le nombre de demandes d’I/O (commandes SCSI) qui peuvent être mis en attente à un moment donné sur un contrôleur de stockage. Chaque demande d’I/O depuis un initiateur HBA d’un hôte vers le contrôleur de stockage consomme une entrée en file d’attente. Quand la file d’attente atteint sa valeur maximale, le contrôleur rejette les commandes entrantes en renvoyant une réponse QFULL (file d’attente pleine).

      Malgré qu’une baie puisse avoir 2 ports par contrôleur, un hyperviseur (ESXi) n’utilise qu’un seul des chemins actif pour l’envoi d’un I/O. De ce fait, lors du calcul de la file d’attente, vous utilisez uniquement un seul chemin actif vers l’un des ports d’un contrôleur de la baie. C’est pour cette raison que la valeur de « P » dans le calcul est de 1.

      De plus, chaque port d’un contrôleur ne possède pas forcement une file d’attente de 2048. La valeur de la file d’attente par port peut varier en fonction du modèle de la baie de stockage (entre 256 et 2048).
      Le « Target Port Queue Depth » dans le calcul représente la max-queue-depth au niveau du contrôleur de la baie et non la max-queue-depth par port. En fonction du modèle de la baie, on retrouve une max-queue-depth de 512 à 2048 par port. (4 ports x 512 = 2048 | 4 ports x 2048 = 8192)

      J’ai ajouté quelques précisions sur l’article.
      Merci de votre retour.

      Au pire si on considère qu’on est en iSCSI et ALUA, cela fait tout de même 2 ports utilisables en même temps pour servir un même LUN non ?

      En effet, l’ALUA permet de rendre visible une LUN par les deux contrôleurs d’une baie. Chaque contrôleur est en mode actif et chacun est capable de recevoir les I/Os. Nous allons avoir une notion de chemin optimisé et non optimisé. Le chemin optimisé est le chemin direct via le contrôleur qui détient la LUN. Le chemin non optimisé est un chemin indirect qui passe par le contrôleur qui ne détient la LUN et qui par un bus d’interconnexion interne va adresser les I/Os au contrôleur qui détient la LUN. (Par contre, un seul des contrôleurs va traiter la requête)
      Dans le cas de vSphere, l’hyperviseur connait les chemins optimisés et envoi les I/O de préférence sur les chemins optimisés (contrôleur qui détient la LUN, sauf en cas de problème sur le contrôleur).

      • vBlackCat dit :

        Bonjour,

        Merci pour votre réponse. Certes, il n’y a qu’un seul chemin actif par datastore et par ESXi, mais ça ne veut pas dire que les 10 ESXi vont tous taper sur le même port de la baie au même moment (sinon quel intérêt d’avoir plusieurs ports ??). D’ailleurs sur une baie de type Equallogic par exemple, c’est même la baie qui va répartir la charge sur ses ports pour s’en assurer si l’on installe le pilote MEM ! Donc je suis d’accord avec vous pour le choix de la valeur de P = 1, mais quand il y’a plusieurs ESXi dans l’équation, je pense toujours qu’il faut prendre en compte le nombre de ports de la baie quand on veut faire un calcul de saturation.

        Après je suis en revanche d’accord avec vous si vous considérez que 2048 est la valeur de la queue globale du controleur de la baie (Mais il y’a tout de même 2 controleurs si la baie est de type actif/actif 😉 ). Mais dans ce cas ce n’est valable que si cette valeur est plus faible que l’addition des 4 queues des ports car si on veut s’assurer de ne pas saturer la baie, alors il faut prendre comme base de calcul la valeur la plus faible des 2 entre la taille de la queue globale du controleur ou la somme des queues des front-end ports.

        En ce qui concerne l’ALUA, vous m’avez mal compris. Je ne disais pas 2 chemins en pensant au chemin optimisé et au chemin non-optimisé, je pensais justement que ça faisait 2 chemins au lieu de 4 car je ne prenais en compte que les 2 chemins vers le controleur propriétaire du LUN. C’était simplement pour dire que au pire, on peut au moins multipier le résultat par 2 dans le pire des cas au lieu de 4 mais c’était idiot car en principe, si le SAN Design a été bien fait, les LUNs devraient être équitablement répartis entre les 2 contrôleurs et donc la charge sur les 4 chemins de l’ESXi et sur les 4 ports de la baie aussi.

        Qu’en pensez-vous ? Y’a t’il une erreur dans mon raisonnement ?

        • Philippe LIMA dit :

          Certes, il n’y a qu’un seul chemin actif par datastore et par ESXi, mais ça ne veut pas dire que les 10 ESXi vont tous taper sur le même port de la baie au même moment (sinon quel intérêt d’avoir plusieurs ports ??).

          Oui, bien entendu dans le cas de plusieurs hyperviseurs ESXi. Ces derniers, vont adresser les I/Os aux différents ports d’un contrôleur de la baie (actif/passif) ou aux différents ports des contrôleurs de la baie (actif/actif).

          D’ailleurs sur une baie de type Equallogic par exemple, c’est même la baie qui va répartir la charge sur ses ports pour s’en assurer si l’on installe le pilote MEM !

          De mémoire la gamme Dell Equallogic sont des baies uniquement de type Actif/Passif. (Avec la possibilité de gérer du failover vertical sur les interfaces des contrôleurs)
          La répartition sur Equallogic dépend surtout de la politique PSP configurée sur l’hyperviseur. Sur une politique PSP en mode (Fixed), pour un hyperviseur accédant à un LUN, il n’y aura pas de répartition de charge sur les différentes interfaces de la baie pour accéder au LUN et le même chemin sera toujours utilisé. Avec une PSP en (Round Robin) il est possible d’exploiter les différents ports du contrôleur. Nous aurons une répartition de 1000 I/O par chemin découvert.

          Le plugin de multipathing Equallogic (MEM) va surtout modifier la valeur par défaut de répartition du nombre d’I/O par chemin de VMware (du Round Robin optimisé pour Equallogic, 3 au lieu de 1000) et du tuning de certaines valeurs avancées. Il me semble que MEM intervient surtout dans l’optimisation des connexions sur des configurations ou les volumes sont splittés sur de multiples membres Equallogic.

          Donc je suis d’accord avec vous pour le choix de la valeur de P = 1, mais quand il y’a plusieurs ESXi dans l’équation, je pense toujours qu’il faut prendre en compte le nombre de ports de la baie quand on veut faire un calcul de saturation.

          Oui, c’est pour cela que le calcul est basé sur la valeur de la queue globale du contrôleur de la baie qui représente en théorie (Nbre de port d’un contrôleur x Queue Depth max par port).

          Après je suis en revanche d’accord avec vous si vous considérez que 2048 est la valeur de la queue globale du controleur de la baie (Mais il y’a tout de même 2 controleurs si la baie est de type actif/actif).
          Mais dans ce cas ce n’est valable que si cette valeur est plus faible que l’addition des 4 queues des ports car si on veut s’assurer de ne pas saturer la baie, alors il faut prendre comme base de calcul la valeur la plus faible des 2 entre la taille de la queue globale du controleur ou la somme des queues des front-end ports.

          Dans le cas d’une baie actif/actif (il en existe de deux types):

          (1) Symmetric active/active
          Plusieurs hyperviseurs vont envoyer des I/O vers les deux contrôleurs actifs. Potentiellement, si nous avons 2 ports par contrôleur nous allons avoir 4 ports « Active (I/O) » (optimized paths) exploitables sur la baie sans notion de priorité de chemin vers les LUNs. Dans ce cas, la valeur limite va être la maximum queue depth des deux contrôleurs de la baie qui bien souvent est : ((Nbre de port d’un contrôleur x Queue Depth max par port) x Nbre de Contrôleur).
          Sur une baie avec une activité I/O très élevée, il convient de faire attention car en cas de défaillance d’un des contrôleurs actifs, le contrôleur restant doit être en mesure d’absorber la charge I/O sur ces ports. Sinon, risque de (status QFULL) sur le(s) port(s) de la baie, puis que le contrôleur demande à l’hôte ESXi de suspendre les nouvelles demandes I/O et que le VMkernel diminue la ou les queue(s) de(s) LUN.

          (2) Asymmetric active/active
          Sur une baie en ALUA, des hyperviseurs équipés d’une carte HBA dual ports en SATP ALUA, et un PSP en Round Robin, plusieurs ESXi vont envoyer des I/O vers les deux contrôleurs actifs en fonction du LUN sollicité. Potentiellement, si nous avons 2 ports par contrôleurs, nous allons avoir 4 ports exploitables sur la baie. Les 2 ports de chaque contrôleur seront répartis sur un switch1 et un switch2.

          Exemple d’accès à un LUN détenu par le Contrôleur 1 :

          2 paths « Active (I/O) » (optimized paths) :
          1) ESXi HBA1 -> Switch1 -> Controller1 (LUN Owner) port1
          2) ESXi HBA2 -> Switch2 -> Controller1 (LUN Owner) port2

          2 paths « Active » (non-optimized paths) :
          3) ESXi HBA1 -> Switch1 -> Controller2 LUN (No Owner) port1 -> Internal Bus -> Controller1 (LUN Owner)
          4) ESXi HBA2 -> Switch2 -> Controller2 LUN (No Owner) port2 -> Internal Bus -> Controller1 (LUN Owner)

          L’hyperviseur va de préférence envoyer les I/O vers les « Active (I/O) » (optimized paths) sur les ports des contrôleurs qui détiennent les LUN mais cela ne veut pas dire qu’ils ne passeront jamais par les « Active » (non-optimized paths).
          Mais dans ce cas aussi, les 4 ports de la baie vont être exploités par les différents ESXi selon qu’ils doivent accéder à un LUN détenu par le contrôleur 1 ou 2.

          En ce qui concerne l’ALUA, vous m’avez mal compris. Je ne disais pas 2 chemins en pensant au chemin optimisé et au chemin non-optimisé, je pensais justement que ça faisait 2 chemins au lieu de 4 car je ne prenais en compte que les 2 chemins vers le controleur propriétaire du LUN. C’était simplement pour dire que au pire, on peut au moins multipier le résultat par 2 dans le pire des cas au lieu de 4 mais c’était idiot car en principe, si le SAN Design a été bien fait, les LUNs devraient être équitablement répartis entre les 2 contrôleurs et donc la charge sur les 4 chemins de l’ESXi et sur les 4 ports de la baie aussi.

          Effectivement, si le SAN Design est correctement fait et que la répartition des LUN est faite équitablement entre les 2 contrôleurs. Chaque ESXi utilisera en priorité ces 2 chemins « Active (I/O) » (optimized paths) vers les ports du contrôleur propriétaire de la LUN sollicitée. (et donc une charge sur les 4 chemins (ESXi) disponibles vers les 4 ports de la baie pour accéder aux multiples LUN)

          Qu’en pensez-vous ? Y’a t’il une erreur dans mon raisonnement ?

          Votre raisonnement est bon. Il a même permis d’enrichir ce post et permettra sûrement d’aider d’autres personnes avec les mêmes interrogations. 😉
          Merci de votre retour.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*