Rechercher

18.6. Optimiser les performances de l'unité centrale de la machine virtuelle

download PDF

Tout comme les processeurs physiques des machines hôtes, les vCPU sont essentiels aux performances des machines virtuelles (VM). Par conséquent, l'optimisation des vCPU peut avoir un impact significatif sur l'efficacité des ressources de vos VM. Pour optimiser votre vCPU :

  1. Ajustez le nombre d'unités centrales attribuées à la VM. Vous pouvez effectuer cette opération à l'aide du CLI ou de la console Web.
  2. Assurez-vous que le modèle vCPU est aligné sur le modèle CPU de l'hôte. Par exemple, pour configurer la VM testguest1 afin qu'elle utilise le modèle de CPU de l'hôte :

    # virt-xml testguest1 --edit --cpu host-model

    Sur un système ARM 64, utilisez --cpu host-passthrough.

  3. Gérer la fusion des pages identiques du noyau (KSM).
  4. Si votre machine hôte utilise l'accès non uniforme à la mémoire (NUMA), vous pouvez également consulter le site configure NUMA pour ses machines virtuelles. Les processus de l'unité centrale et de la mémoire de l'hôte sont ainsi mappés au plus près des processus de l'unité centrale et de la mémoire de la VM. En effet, le réglage NUMA fournit au vCPU un accès plus rationnel à la mémoire système allouée à la VM, ce qui peut améliorer l'efficacité de traitement du vCPU.

    Pour plus de détails, voir Configuration de NUMA dans une machine virtuelle et Exemple de scénario d'optimisation des performances vCPU.

18.6.1. Ajout et suppression de CPU virtuels à l'aide de l'interface de ligne de commande

Pour augmenter ou optimiser les performances du processeur d'une machine virtuelle (VM), vous pouvez ajouter ou supprimer des processeurs virtuels (vCPU) assignés à la VM.

Lorsqu'elle est effectuée sur une VM en cours d'exécution, cette opération est également appelée vCPU hot plugging et hot unplugging (branchement et débranchement à chaud des vCPU). Cependant, notez que le vCPU hot unplug n'est pas pris en charge dans RHEL 9, et Red Hat déconseille fortement son utilisation.

Conditions préalables

  • Optional: Affichez l'état actuel des vCPU de la VM ciblée. Par exemple, pour afficher le nombre de vCPU sur la VM testguest:

    # virsh vcpucount testguest
    maximum      config         4
    maximum      live           2
    current      config         2
    current      live           1

    Cette sortie indique que testguest utilise actuellement 1 vCPU, et qu'il est possible d'y connecter à chaud 1 vCPU supplémentaire pour augmenter les performances de la VM. Cependant, après le redémarrage, le nombre de vCPUs utilisées par testguest passera à 2, et il sera possible de brancher à chaud 2 vCPUs supplémentaires.

Procédure

  1. Ajuste le nombre maximum de vCPU qui peuvent être attachés à une VM, ce qui prend effet au prochain démarrage de la VM.

    Par exemple, pour augmenter le nombre maximum de vCPU pour la VM testguest à 8 :

    # virsh setvcpus testguest 8 --maximum --config

    Notez que le maximum peut être limité par la topologie de l'unité centrale, le matériel de l'hôte, l'hyperviseur et d'autres facteurs.

  2. Ajustez le nombre actuel de vCPUs attachés à une VM, jusqu'au maximum configuré à l'étape précédente. Par exemple :

    • Pour augmenter le nombre de vCPU attachés à la VM testguest en cours d'exécution à 4 :

      # virsh setvcpus testguest 4 --live

      Cela augmente les performances de la VM et l'empreinte de la charge de l'hôte de testguest jusqu'au prochain démarrage de la VM.

    • Pour réduire de façon permanente le nombre de vCPUs attachés à la VM testguest à 1 :

      # virsh setvcpus testguest 1 --config

      Cela diminue les performances de la VM et l'empreinte de la charge de l'hôte sur testguest après le prochain démarrage de la VM. Toutefois, si nécessaire, des vCPU supplémentaires peuvent être connectées à chaud à la VM pour augmenter temporairement ses performances.

Vérification

  • Confirmez que l'état actuel de vCPU pour la VM reflète vos changements.

    # virsh vcpucount testguest
    maximum      config         8
    maximum      live           4
    current      config         1
    current      live           4

18.6.2. Gestion des CPU virtuels à l'aide de la console web

En utilisant la console web RHEL 9, vous pouvez examiner et configurer les CPU virtuels utilisés par les machines virtuelles (VM) auxquelles la console web est connectée.

Conditions préalables

Procédure

  1. Dans l'interface Machines virtuelles, cliquez sur la VM dont vous voulez voir les informations.

    Une nouvelle page s'ouvre avec une section Vue d'ensemble contenant des informations de base sur la VM sélectionnée et une section Console permettant d'accéder à l'interface graphique de la VM.

  2. Cliquez sur modifier en regard du nombre de vCPU dans le volet Vue d'ensemble.

    La boîte de dialogue vCPU details apparaît.

    Image displaying the VM CPU details dialog box.
  1. Configurer les CPU virtuels pour la VM sélectionnée.

    • vCPU Count - Le nombre de vCPUs actuellement utilisés.

      Note

      Le nombre de vCPU ne peut pas être supérieur au maximum de vCPU.

    • vCPU Maximum - Le nombre maximum de CPU virtuels qui peuvent être configurés pour la VM. Si cette valeur est supérieure à vCPU Count, des vCPU supplémentaires peuvent être attachés à la VM.
    • Sockets - Le nombre de sockets à exposer à la VM.
    • Cores per socket - Le nombre de cœurs pour chaque socket à exposer à la VM.
    • Threads per core - Le nombre de threads pour chaque cœur à exposer à la VM.

      Notez que les options Sockets, Cores per socket, et Threads per core ajustent la topologie du CPU de la VM. Cela peut être bénéfique pour les performances du vCPU et peut avoir un impact sur la fonctionnalité de certains logiciels dans le système d'exploitation invité. Si un paramètre différent n'est pas requis par votre déploiement, conservez les valeurs par défaut.

  2. Cliquez sur Appliquer.

    Les CPU virtuels de la VM sont configurés.

    Note

    Les modifications apportées aux paramètres de l'unité centrale virtuelle ne prennent effet qu'après le redémarrage de la VM.

18.6.3. Configurer NUMA dans une machine virtuelle

Les méthodes suivantes peuvent être utilisées pour configurer les paramètres NUMA (Non-Uniform Memory Access) d'une machine virtuelle (VM) sur un hôte RHEL 9.

Conditions préalables

  • L'hôte est une machine compatible NUMA. Pour savoir si c'est le cas, utilisez la commande virsh nodeinfo et consultez la ligne NUMA cell(s):

    # virsh nodeinfo
    CPU model:           x86_64
    CPU(s):              48
    CPU frequency:       1200 MHz
    CPU socket(s):       1
    Core(s) per socket:  12
    Thread(s) per core:  2
    NUMA cell(s):        2
    Memory size:         67012964 KiB

    Si la valeur de la ligne est égale ou supérieure à 2, l'hôte est compatible NUMA.

Procédure

Pour faciliter l'utilisation, vous pouvez mettre en place la configuration NUMA d'une VM à l'aide d'utilitaires et de services automatisés. Toutefois, une configuration NUMA manuelle est plus susceptible de produire une amélioration significative des performances.

Automatic methods

  • Définissez la politique NUMA de la VM sur Preferred. Par exemple, pour la VM testguest5:

    # virt-xml testguest5 --edit --vcpus placement=auto
    # virt-xml testguest5 --edit --numatune mode=preferred
  • Activer l'équilibrage automatique des NUMA sur l'hôte :

    # echo 1 > /proc/sys/kernel/numa_balancing
  • Démarrez le service numad pour aligner automatiquement le processeur de la VM sur les ressources mémoire.

    # systemctl start numad

Manual methods

  1. Affecter des threads vCPU spécifiques à un processeur hôte spécifique ou à une gamme de processeurs. Ceci est également possible sur les hôtes et les VMs non-NUMA, et est recommandé comme méthode sûre d'amélioration des performances vCPU.

    Par exemple, les commandes suivantes épinglent les threads vCPU 0 à 5 de la VM testguest6 aux CPU 1, 3, 5, 7, 9 et 11 de l'hôte, respectivement :

    # virsh vcpupin testguest6 0 1
    # virsh vcpupin testguest6 1 3
    # virsh vcpupin testguest6 2 5
    # virsh vcpupin testguest6 3 7
    # virsh vcpupin testguest6 4 9
    # virsh vcpupin testguest6 5 11

    Vous pouvez ensuite vérifier si l'opération s'est déroulée correctement :

    # virsh vcpupin testguest6
    VCPU   CPU Affinity
    ----------------------
    0      1
    1      3
    2      5
    3      7
    4      9
    5      11
  2. Après avoir épinglé les threads vCPU, vous pouvez également épingler les threads de processus QEMU associés à une VM spécifique à un processeur hôte spécifique ou à une plage de processeurs. Par exemple, les commandes suivantes épinglent le thread de processus QEMU de testguest6 aux CPU 13 et 15, et vérifient que cela a réussi :

    # virsh emulatorpin testguest6 13,15
    # virsh emulatorpin testguest6
    emulator: CPU Affinity
    ----------------------------------
           *: 13,15
  3. Enfin, vous pouvez également spécifier les nœuds NUMA de l'hôte qui seront affectés spécifiquement à une certaine VM. Cela peut améliorer l'utilisation de la mémoire de l'hôte par le vCPU de la VM. Par exemple, les commandes suivantes configurent testguest6 pour qu'il utilise les nœuds NUMA 3 à 5, et vérifient que l'opération a réussi :

    # virsh numatune testguest6 --nodeset 3-5
    # virsh numatune testguest6
Note

Pour obtenir les meilleurs résultats, il est recommandé d'utiliser toutes les méthodes de réglage manuel énumérées ci-dessus

18.6.4. Exemple de scénario d'optimisation des performances des vCPU

Pour obtenir la meilleure performance vCPU possible, Red Hat recommande d'utiliser les paramètres manuels vcpupin, emulatorpin, et numatune ensemble, par exemple comme dans le scénario suivant.

Scénario de départ

  • Votre hôte présente les caractéristiques matérielles suivantes :

    • 2 nœuds NUMA
    • 3 cœurs de CPU sur chaque nœud
    • 2 threads sur chaque cœur

    La sortie de virsh nodeinfo d'une telle machine ressemblerait à ce qui suit :

    # virsh nodeinfo
    CPU model:           x86_64
    CPU(s):              12
    CPU frequency:       3661 MHz
    CPU socket(s):       2
    Core(s) per socket:  3
    Thread(s) per core:  2
    NUMA cell(s):        2
    Memory size:         31248692 KiB
  • Vous avez l'intention de modifier une VM existante pour qu'elle ait 8 vCPU, ce qui signifie qu'elle ne tiendra pas dans un seul nœud NUMA.

    Par conséquent, vous devez distribuer 4 vCPU sur chaque nœud NUMA et faire en sorte que la topologie des vCPU ressemble le plus possible à la topologie de l'hôte. Cela signifie que les vCPU qui s'exécutent en tant que threads frères d'une unité centrale physique donnée doivent être rattachées à des threads hôtes sur le même cœur. Pour plus de détails, voir le site Solution ci-dessous :

Solution

  1. Obtenir des informations sur la topologie de l'hôte :

    # virsh capabilities

    Le résultat doit comprendre une section qui ressemble à ce qui suit :

    <topology>
      <cells num="2">
        <cell id="0">
          <memory unit="KiB">15624346</memory>
          <pages unit="KiB" size="4">3906086</pages>
          <pages unit="KiB" size="2048">0</pages>
          <pages unit="KiB" size="1048576">0</pages>
          <distances>
            <sibling id="0" value="10" />
            <sibling id="1" value="21" />
          </distances>
          <cpus num="6">
            <cpu id="0" socket_id="0" core_id="0" siblings="0,3" />
            <cpu id="1" socket_id="0" core_id="1" siblings="1,4" />
            <cpu id="2" socket_id="0" core_id="2" siblings="2,5" />
            <cpu id="3" socket_id="0" core_id="0" siblings="0,3" />
            <cpu id="4" socket_id="0" core_id="1" siblings="1,4" />
            <cpu id="5" socket_id="0" core_id="2" siblings="2,5" />
          </cpus>
        </cell>
        <cell id="1">
          <memory unit="KiB">15624346</memory>
          <pages unit="KiB" size="4">3906086</pages>
          <pages unit="KiB" size="2048">0</pages>
          <pages unit="KiB" size="1048576">0</pages>
          <distances>
            <sibling id="0" value="21" />
            <sibling id="1" value="10" />
          </distances>
          <cpus num="6">
            <cpu id="6" socket_id="1" core_id="3" siblings="6,9" />
            <cpu id="7" socket_id="1" core_id="4" siblings="7,10" />
            <cpu id="8" socket_id="1" core_id="5" siblings="8,11" />
            <cpu id="9" socket_id="1" core_id="3" siblings="6,9" />
            <cpu id="10" socket_id="1" core_id="4" siblings="7,10" />
            <cpu id="11" socket_id="1" core_id="5" siblings="8,11" />
          </cpus>
        </cell>
      </cells>
    </topology>
  2. Optional: Testez les performances de la VM en utilisant les outils et utilitaires appropriés.
  3. Mettre en place et monter des pages gigantesques de 1 GiB sur l'hôte :

    Note

    il se peut que certaines architectures et configurations, telles que les hôtes ARM 64, ne disposent pas d'énormes pages de 1 gigaoctet.

    1. Ajoutez la ligne suivante à la ligne de commande du noyau de l'hôte :

      default_hugepagesz=1G hugepagesz=1G
    2. Créez le fichier /etc/systemd/system/hugetlb-gigantic-pages.service avec le contenu suivant :

      [Unit]
      Description=HugeTLB Gigantic Pages Reservation
      DefaultDependencies=no
      Before=dev-hugepages.mount
      ConditionPathExists=/sys/devices/system/node
      ConditionKernelCommandLine=hugepagesz=1G
      
      [Service]
      Type=oneshot
      RemainAfterExit=yes
      ExecStart=/etc/systemd/hugetlb-reserve-pages.sh
      
      [Install]
      WantedBy=sysinit.target
    3. Créez le fichier /etc/systemd/hugetlb-reserve-pages.sh avec le contenu suivant :

      #!/bin/sh
      
      nodes_path=/sys/devices/system/node/
      if [ ! -d $nodes_path ]; then
      	echo "ERROR: $nodes_path does not exist"
      	exit 1
      fi
      
      reserve_pages()
      {
      	echo $1 > $nodes_path/$2/hugepages/hugepages-1048576kB/nr_hugepages
      }
      
      reserve_pages 4 node1
      reserve_pages 4 node2

      Cela réserve quatre grandes pages de 1GiB de node1 et quatre grandes pages de 1GiB de node2.

    4. Rendez exécutable le script créé à l'étape précédente :

      # chmod x /etc/systemd/hugetlb-reserve-pages.sh
    5. Activer la réservation d'une grande page au démarrage :

      # systemctl enable hugetlb-gigantic-pages
  4. Utilisez la commande virsh edit pour éditer la configuration XML de la VM que vous souhaitez optimiser, dans cet exemple super-VM:

    # virsh edit super-vm
  5. Ajustez la configuration XML de la VM de la manière suivante :

    1. Configurez la VM pour qu'elle utilise 8 vCPU statiques. Pour ce faire, utilisez l'élément <vcpu/>.
    2. Épinglez chacun des threads vCPU aux threads correspondants de l'unité centrale de l'hôte qu'il reflète dans la topologie. Pour ce faire, utilisez les éléments <vcpupin/> dans la section <cputune>.

      Notez que, comme le montre l'utilitaire virsh capabilities ci-dessus, les threads du processeur hôte ne sont pas ordonnés de manière séquentielle dans leurs cœurs respectifs. En outre, les threads vCPU doivent être rattachés à l'ensemble le plus élevé de cœurs hôtes disponibles sur le même nœud NUMA. Pour une illustration sous forme de tableau, voir la section Sample topology ci-dessous.

      La configuration XML pour les étapes a. et b. peut ressembler à ce qui suit :

      <cputune>
        <vcpupin vcpu='0' cpuset='1'/>
        <vcpupin vcpu='1' cpuset='4'/>
        <vcpupin vcpu='2' cpuset='2'/>
        <vcpupin vcpu='3' cpuset='5'/>
        <vcpupin vcpu='4' cpuset='7'/>
        <vcpupin vcpu='5' cpuset='10'/>
        <vcpupin vcpu='6' cpuset='8'/>
        <vcpupin vcpu='7' cpuset='11'/>
        <emulatorpin cpuset='6,9'/>
      </cputune>
    3. Configurez la VM pour qu'elle utilise 1 GiB de pages énormes :

      <memoryBacking>
        <hugepages>
          <page size='1' unit='GiB'/>
        </hugepages>
      </memoryBacking>
    4. Configurez les nœuds NUMA de la VM pour qu'ils utilisent la mémoire des nœuds NUMA correspondants de l'hôte. Pour ce faire, utilisez les éléments <memnode/> dans la section <numatune/>:

      <numatune>
        <memory mode="preferred" nodeset="1"/>
        <memnode cellid="0" mode="strict" nodeset="0"/>
        <memnode cellid="1" mode="strict" nodeset="1"/>
      </numatune>
    5. Assurez-vous que le mode de l'unité centrale est réglé sur host-passthrough et que l'unité centrale utilise la mémoire cache en mode passthrough:

      <cpu mode="host-passthrough">
        <topology sockets="2" cores="2" threads="2"/>
        <cache mode="passthrough"/>

      Sur un système ARM 64, omettre la ligne <cache mode="passthrough"/>.

Vérification

  1. Confirmez que la configuration XML résultante de la VM comprend une section similaire à la suivante :

    [...]
      <memoryBacking>
        <hugepages>
          <page size='1' unit='GiB'/>
        </hugepages>
      </memoryBacking>
      <vcpu placement='static'>8</vcpu>
      <cputune>
        <vcpupin vcpu='0' cpuset='1'/>
        <vcpupin vcpu='1' cpuset='4'/>
        <vcpupin vcpu='2' cpuset='2'/>
        <vcpupin vcpu='3' cpuset='5'/>
        <vcpupin vcpu='4' cpuset='7'/>
        <vcpupin vcpu='5' cpuset='10'/>
        <vcpupin vcpu='6' cpuset='8'/>
        <vcpupin vcpu='7' cpuset='11'/>
        <emulatorpin cpuset='6,9'/>
      </cputune>
      <numatune>
        <memory mode="preferred" nodeset="1"/>
        <memnode cellid="0" mode="strict" nodeset="0"/>
        <memnode cellid="1" mode="strict" nodeset="1"/>
      </numatune>
      <cpu mode="host-passthrough">
        <topology sockets="2" cores="2" threads="2"/>
        <cache mode="passthrough"/>
        <numa>
          <cell id="0" cpus="0-3" memory="2" unit="GiB">
            <distances>
              <sibling id="0" value="10"/>
              <sibling id="1" value="21"/>
            </distances>
          </cell>
          <cell id="1" cpus="4-7" memory="2" unit="GiB">
            <distances>
              <sibling id="0" value="21"/>
              <sibling id="1" value="10"/>
            </distances>
          </cell>
        </numa>
      </cpu>
    </domain>
  2. Optional: Tester les performances de la VM en utilisant les outils et utilitaires applicables pour évaluer l'impact de l'optimisation de la VM.

Exemple de topologie

  • Les tableaux suivants illustrent les connexions entre les vCPU et les CPU hôtes auxquels ils doivent être rattachés :

    Tableau 18.2. Topologie de l'hôte

    CPU threads

    0

    3

    1

    4

    2

    5

    6

    9

    7

    10

    8

    11

    Cores

    0

    1

    2

    3

    4

    5

    Sockets

    0

    1

    NUMA nodes

    0

    1

    Tableau 18.3. Topologie de la VM

    vCPU threads

    0

    1

    2

    3

    4

    5

    6

    7

    Cores

    0

    1

    2

    3

    Sockets

    0

    1

    NUMA nodes

    0

    1

    Tableau 18.4. Topologie combinée d'hôtes et de machines virtuelles

    vCPU threads

     

    0

    1

    2

    3

     

    4

    5

    6

    7

    Host CPU threads

    0

    3

    1

    4

    2

    5

    6

    9

    7

    10

    8

    11

    Cores

    0

    1

    2

    3

    4

    5

    Sockets

    0

    1

    NUMA nodes

    0

    1

    Dans ce scénario, il y a 2 nœuds NUMA et 8 vCPU. Par conséquent, 4 threads vCPU doivent être épinglés sur chaque nœud.

    De plus, Red Hat recommande de laisser au moins un thread de CPU disponible sur chaque nœud pour les opérations du système hôte.

    Étant donné que dans cet exemple, chaque nœud NUMA héberge 3 cœurs, chacun avec 2 threads de l'unité centrale, l'ensemble pour le nœud 0 se traduit comme suit :

    <vcpupin vcpu='0' cpuset='1'/>
    <vcpupin vcpu='1' cpuset='4'/>
    <vcpupin vcpu='2' cpuset='2'/>
    <vcpupin vcpu='3' cpuset='5'/>

18.6.5. Gestion de la fusion de pages identiques dans le noyau

Le Kernel Same-Page Merging (KSM) améliore la densité de la mémoire en partageant des pages de mémoire identiques entre les machines virtuelles (VM). Cependant, l'activation de KSM augmente l'utilisation du processeur et peut nuire aux performances globales en fonction de la charge de travail.

En fonction de vos besoins, vous pouvez activer ou désactiver KSM pour une session unique ou de façon permanente.

Note

Dans RHEL 9 et les versions ultérieures, KSM est désactivé par défaut.

Conditions préalables

  • Accès à la racine de votre système hôte.

Procédure

  • Désactiver KSM :

    • Pour désactiver KSM pour une seule session, utilisez l'utilitaire systemctl pour arrêter les services ksm et ksmtuned.

      # systemctl stop ksm
      
      # systemctl stop ksmtuned
    • Pour désactiver KSM de manière persistante, utilisez l'utilitaire systemctl pour désactiver les services ksm et ksmtuned.

      # systemctl disable ksm
      Removed /etc/systemd/system/multi-user.target.wants/ksm.service.
      # systemctl disable ksmtuned
      Removed /etc/systemd/system/multi-user.target.wants/ksmtuned.service.
Note

Les pages de mémoire partagées entre les machines virtuelles avant la désactivation de KSM resteront partagées. Pour arrêter le partage, supprimez toutes les pages PageKSM dans le système à l'aide de la commande suivante :

# echo 2 > /sys/kernel/mm/ksm/run

Une fois que les pages anonymes ont remplacé les pages KSM, le service du noyau khugepaged reconstruit les hugepages transparentes sur la mémoire physique de la VM.

  • Activer KSM :
Avertissement

L'activation de KSM augmente l'utilisation de l'unité centrale et affecte les performances globales de l'unité centrale.

  1. Installer le service ksmtuned:

    # dnf install ksmtuned

  2. Démarrer le service :

    • Pour activer KSM pour une seule session, utilisez l'utilitaire systemctl pour démarrer les services ksm et ksmtuned.

      # systemctl start ksm
      # systemctl start ksmtuned
    • Pour activer KSM de manière persistante, utilisez l'utilitaire systemctl pour activer les services ksm et ksmtuned.

      # systemctl enable ksm
      Created symlink /etc/systemd/system/multi-user.target.wants/ksm.service  /usr/lib/systemd/system/ksm.service
      
      # systemctl enable ksmtuned
      Created symlink /etc/systemd/system/multi-user.target.wants/ksmtuned.service  /usr/lib/systemd/system/ksmtuned.service
Red Hat logoGithubRedditYoutubeTwitter

Apprendre

Essayez, achetez et vendez

Communautés

À propos de la documentation Red Hat

Nous aidons les utilisateurs de Red Hat à innover et à atteindre leurs objectifs grâce à nos produits et services avec un contenu auquel ils peuvent faire confiance.

Rendre l’open source plus inclusif

Red Hat s'engage à remplacer le langage problématique dans notre code, notre documentation et nos propriétés Web. Pour plus de détails, consultez leBlog Red Hat.

À propos de Red Hat

Nous proposons des solutions renforcées qui facilitent le travail des entreprises sur plusieurs plates-formes et environnements, du centre de données central à la périphérie du réseau.

© 2024 Red Hat, Inc.