Fermer

août 19, 2021

Docker Bootcamp – Comprendre les performances et leur réglage


Bienvenue au bootcamp docker. Dans un article précédent, nous avons appris à définir des limites de ressources pour nos conteneurs. Dans cet article, nous approfondirons les performances. Nous commencerons par une brève leçon d'histoire sur les processeurs et l'hyperthreading, puis passerons à un exemple qui aidera à expliquer comment différents processeurs peuvent avoir un impact sur les performances. Nous examinerons quelques façons d'examiner nos conteneurs et de les ajuster pour des performances accrues.

  • Socket – Un connecteur physique sur la carte mère où un processeur peut être connecté. Certaines cartes mères ont plusieurs sockets et peuvent prendre en charge plusieurs processeurs.
  • CPU (Central Processing Unit AKA Processor) – Un circuit électronique complexe qui contient plusieurs sous-composants nécessaires pour exécuter des applications.
  • CPU Core – Le sous-composant de la CPU qui inclut le cache L1 et exécute les instructions. De nombreux processeurs ont plusieurs cœurs.
  • CPU multicœur -Permet à plusieurs instructions d'être exécutées en parallèle sur différents cœurs.
  • CPU Scheduler – Permet à un seul processeur de partager des ressources système entre plusieurs processus. Il sélectionne un processus dans la file d'attente qui est prêt à être exécuté.
  • Multi-threading simultané (AKA Hyperthreading) – Permet au planificateur de processeur d'attribuer deux tâches au même cœur de processeur.
  • Cœurs physiques – Un nombre réel de cœurs pour tous les processeurs.
  • Processeurs logiques – Un nombre de cœurs physiques multiplié par deux (si l'hyperthreading est activé).

Les premiers ordinateurs modernes avaient un processeur et pouvaient n'exécute qu'une instruction à la fois. Les grands ordinateurs serveurs avaient plusieurs sockets pour plusieurs processeurs afin de permettre une exécution parallèle et d'augmenter les performances. En 2002, Intel a introduit la technologie d'hyperthreading pour améliorer les performances d'un seul cœur de processeur. Un processeur s'affiche comme deux processeurs logiques pour le système d'exploitation. Chaque processeur logique peut exécuter des instructions et être interrompu ou arrêté indépendamment. Cela ne double pas les performances du CPU car le CPU ne peut toujours traiter qu'une instruction à la fois. Les processeurs ultérieurs comprenaient plusieurs cœurs pour permettre une véritable exécution parallèle. Les processeurs d'aujourd'hui ont à la fois plusieurs cœurs et prennent en charge l'hyperthreading pour améliorer les performances de tous les cœurs disponibles.

Utilisons un exemple pour comprendre le fonctionnement de notre processeur. Imaginez un bol de bonbons. Les bonbons représentent les instructions de l'ordinateur. Votre bouche représente le processeur qui traite les instructions. Vos mains représentent le planificateur CPU qui sélectionne une instruction à exécuter. Le but est de consommer le bol de bonbons le plus rapidement possible. Vous ne pouvez ramasser qu'un seul bonbon avec chaque main à la fois. Vous devez complètement mâcher et avaler ce bonbon avant de ramasser le prochain bonbon. Appliquons ce scénario à différents types de processeurs.

  • Processeur monocœur sans hyperthreading – Utilisez uniquement votre main droite. Prenez un bonbon et mangez.
  • Processeur monocœur avec hyperthreading – Utilisez les deux mains. Prenez un bonbon avec votre main droite et mangez. Pendant que vous mangez, prenez un autre bonbon avec votre main gauche et faites-le attendre près de votre bouche lorsque vous aurez terminé le premier bonbon.
  • Processeur double cœur sans hyperthreading – Demandez à une autre personne de vous rejoindre. Chaque personne ne peut utiliser que sa main droite. Chaque personne prend un bonbon et mange.
  • Processeur double cœur avec hyperthreading – Demandez à une autre personne de vous rejoindre. Chaque personne peut utiliser ses deux mains. Chaque personne prend un bonbon avec sa main droite et mange. Pendant que vous mangez, prenez un autre bonbon avec votre main gauche et faites-le attendre près de votre bouche lorsque vous aurez fini le premier bonbon.

Étendez l'exemple à quatre, six ou huit personnes (noyaux). ) avec et sans hyperthreading. Vous pouvez voir que l'ajout de plus de personnes augmente considérablement la vitesse à laquelle vous pouvez vider le bol. Être capable d'utiliser les deux mains augmente également la vitesse, mais chaque bouche ne peut mâcher qu'un seul bonbon à la fois, donc l'augmentation est moindre que l'ajout d'une autre personne.

L'hyperthreading améliore les performances car il permet au processeur de faire autre chose. choses pendant qu'un thread attend sur un autre matériel (c'est-à-dire mémoire, disque, réseau). Cela se fait au prix d'une production de chaleur légèrement plus élevée et d'une durée de vie légèrement réduite de la batterie. Une application doit être écrite spécifiquement pour tirer parti de l'hyperthreading. Les tâches qui doivent être effectuées dans un ordre séquentiel ne bénéficieront pas de l'hyperthreading. Les tâches telles que le montage vidéo, le rendu 3D, les jeux et d'autres opérations gourmandes en ressources CPU bénéficieront le plus de l'hyperthreading.

J'ai un ordinateur avec un socket, 6 cœurs physiques et 12 processeurs logiques. Lorsque je crée une nouvelle machine virtuelle, on m'offre la possibilité d'affecter 12 processeurs à la VM. Si j'affecte les 12 processeurs logiques à la VM, le planificateur CPU pensera qu'il a 12 cœurs physiques. Cela entraînera l'exécution de chacun des hyperthreads à 50 % d'utilisation et les cœurs à 100 % d'utilisation, ce qui entraînera une dégradation des performances à la fois pour la machine virtuelle et l'hôte. Il est préférable de ne pas affecter plus que le nombre de cœurs physiques à une seule machine virtuelle.

J'aime laisser au moins un cœur entièrement disponible pour l'hôte. Si vous exécutez plusieurs machines virtuelles sur le même hôte, le nombre total de cœurs attribués aux machines virtuelles peut dépasser le nombre de cœurs physiques. C'est ce qu'on appelle le surengagement. Avec plusieurs machines virtuelles fonctionnant sous une charge normale, les performances ne devraient pas se dégrader car chaque machine virtuelle a la possibilité d'utiliser le processeur hôte. Vous pouvez constater une baisse des performances si une ou plusieurs des machines virtuelles ont une charge élevée en continu. Vous pouvez facilement modifier le nombre de processeurs affectés à une machine virtuelle en arrêtant la machine virtuelle et en modifiant les paramètres. L'invité reconnaîtra instantanément les processeurs assignés. Décider du nombre de cœurs à affecter à une VM est un art. Vous ne voulez pas affecter trop peu ou trop de ressources. Les valeurs finales dépendent de la charge de travail exécutée par la machine virtuelle.

Que vous exécutiez vos conteneurs sur votre hôte ou dans une machine virtuelle, votre application subira un impact négatif sur les performances. Heureusement, nous pouvons ajuster les performances de nos conteneurs en ajustant les processeurs et la mémoire. Vous pouvez ajuster le nombre de processeurs disponibles pour le conteneur en utilisant l'indicateur –cpus sur la commande docker create/run ou dans un fichier docker-compose. Si aucune valeur n'est fournie, docker utilisera une valeur par défaut. Sous Windows, un conteneur utilise par défaut deux processeurs. Si l'hyperthreading est disponible, il s'agit d'un cœur et de deux processeurs logiques. Si l'hyperthreading n'est pas disponible, il s'agit de deux cœurs et de deux processeurs logiques. Sous Linux, un conteneur utilise par défaut tous les processeurs disponibles de l'hôte. Tout comme les machines virtuelles, trouver la bonne quantité de ressources est un art. Les valeurs finales dépendent de la charge de travail effectuée par le conteneur. Contrairement aux machines virtuelles, vous ne pouvez pas modifier la configuration d'un conteneur existant, vous devez détruire le conteneur, modifier les paramètres et créer un nouveau conteneur.

Il n'y a pas de formule magique pour déterminer la "bonne" taille pour une VM ou un conteneur. . Cela dépend de la quantité de ressources disponibles sur l'hôte, de la capacité de faire évoluer l'hôte, des exigences de l'application, de la charge moyenne de l'application, de la charge maximale de l'application et des autres applications exécutées sur l'hôte. Docker crée un processus appelé "Vmmem" sur Windows qui représente l'utilisation du processeur et de la mémoire du conteneur. Si le processeur de ce processus s'exécute en permanence à 30 % ou plus, vous pouvez envisager d'augmenter le nombre de processeurs pour le conteneur. Si la mémoire fonctionne constamment à 100 % de la quantité allouée, vous pouvez envisager d'augmenter la quantité de RAM pour le conteneur. La mémoire est un peu plus difficile à évaluer que le processeur, car la mémoire est censée être utilisée à un taux plus élevé pour garder les données d'application rapidement accessibles. Avoir trop peu de mémoire entraîne une lourde charge sur le processeur car il échange des données entre la mémoire et le disque. L'attribution d'une trop grande quantité de mémoire peut entraîner des problèmes de performances pour l'hôte.

  • Hôte.
    • Mon hôte a 6 cœurs et 12 processeurs logiques
    • les informations du système Docker montrent 12 processeurs
  • Machine virtuelle
    • Ma machine virtuelle a 4 cœurs et 4 processeurs logiques
    • les informations du système Docker montrent 4 processeurs
  • Liste des informations sur le processeur
  • Liste du nombre de processeurs en cours d'utilisation
  • Liste des informations sur la mémoire
  • Liste des informations système
    • infos système
      • Remarquez que la section Processeur(s) répertorie le nombre de processeurs installés
      • Remarquez que la section mémoire répertorie la mémoire totale, la mémoire disponible et la mémoire virtuelle
  • Liste des informations sur le processeur
    • CPU WMIC Get DeviceId, NumberOfCores, NumberOfLogicalProcessors (pas d'espace entre les noms de champ)
      • Si l'hyperthreading est activé, le nombre de processeurs logiques sera le double du nombre de cœurs
  • Liste des informations du système Docker
    • informations sur le système Docker
      • Remarquez que la section des processeurs répertorie le nombre de processeurs disponibles pour docker
      • Remarquez que la section pour la mémoire totale répertorie la quantité de RAM disponible pour docker
  • Liste des informations sur le conteneur
    • docker inspecter
      • Remarquez les sections pour HostConfig:NanoCpus, HostConfig:CpuShares, HostConfig:CpusetCpus, HostConfig:Memory
  • Liste des statistiques du conteneur
    • statistiques du docker
      • Affiche l'utilisation du processeur, l'utilisation de la mémoire, la limite de mémoire

J'ai créé plusieurs conteneurs à la fois sur mon hôte et à l'intérieur d'une machine virtuelle en utilisant à la fois des conteneurs Linux et Windows. Les tableaux ci-dessous répertorient les configurations et le nombre de processeurs pour chaque scénario.

Configuration du conteneur LinuxNanoCpusnprocCpuinfo
Hôte – Par défaut01212
Hôte – cpus=44000000000[19659052]1212
Hôte – cpuset-cpu=0,2,40312
VM – Par défaut044
VM – cpus=4400000000044
VM – cpuset-cpu=0,1,2034

 [19659019] Notez que les conteneurs Linux voient tous les processeurs disponibles par défaut. L'utilisation de l'indicateur cpus limite les processeurs en limitant le pourcentage de processeurs disponibles. L'indicateur cpuset-cpu limite le nombre réel de cœurs sur lesquels le conteneur s'exécutera.

Configuration du conteneur WindowsNanoCpusNombre de cœursNombre de processeurs logiques
Hôte – Par défaut012
Hôte – cpus=4[19659051]400000000024
VM – Par défaut022
VM – cpus=4400000000044[19659078] 

Notez que les conteneurs Windows ne voient que deux processeurs par défaut. L'utilisation de l'indicateur cpus limite les processeurs en limitant le pourcentage de processeurs disponibles. L'indicateur cpuset-cpu n'est pas disponible pour les conteneurs Windows.

J'ai créé un conteneur Windows qui exécute iis et héberge un site Web dont le contenu est géré. J'ai ajusté la limite de mémoire pour trouver les meilleurs paramètres. Comme mentionné précédemment, sans mem_limit défini, les conteneurs Windows ont par défaut 1 Go de RAM physique. Il est logique que ce conteneur fonctionnait lentement car il ne disposait que de 36 Mo de RAM libre. En testant différentes valeurs de 2 Go, 3 Go et 4 Go, j'ai remarqué que la quantité de RAM libre avait également augmenté. Pour mon conteneur, il semble que je ne gagne aucun avantage à définir un mem_limit supérieur à 2 Go.

Configuration du conteneur WindowsRam totaleRam disponibleMémoire virtuelleVirtuel disponible
Hôte16Go6,4Go22,5Go5,5Go[19659111]VM (pas de mem_limit défini)1Go36Mo2,7Go1,4Go
VM – mem_limit=2Go2,5Go1,2Go4,2Go[19659110]2,8 Go
VM – mem_limit=3Go3,5Go2,2Go7,1Go5,6Go
VM – mem_limit=4Go4,5Go3,0Go9,2 Go7,4 Go

 

Pour que vos conteneurs fonctionnent correctement, vous ne devez pas faire confiance aux paramètres du docker par défaut. Utilisez les indicateurs cpus et cpuset-cpus lorsque cela est possible. Surveillez votre gestionnaire de tâches pour une utilisation élevée et ajustez les paramètres de votre conteneur si nécessaire. Connectez-vous à la console de votre conteneur pour voir quelles ressources votre conteneur peut voir et comment elles sont utilisées. Vous pouvez améliorer les performances de vos conteneurs en ajustant les paramètres du processeur et de la mémoire, mais votre application ne fonctionnera probablement jamais aussi vite qu'elle le pourrait en dehors d'un conteneur.




Source link