Tests de performances avec les clients Compute Engine

Cette page explique comment tester les performances d'une instance Google Cloud Managed Lustre à l'aide de clients Compute Engine. Il fournit des instructions pour mesurer les performances d'un seul client à l'aide de fio et les performances globales de plusieurs clients à l'aide de l'outil de benchmark IOR.

Mesurer les performances d'un seul client

Pour tester les performances de lecture et d'écriture à partir d'un seul client Compute Engine, utilisez l'outil en ligne de commande fio (Flexible I/O tester).

  1. Installez fio :

    Rocky 8

    sudo dnf install fio -y
    

    Ubuntu 20.04 et 22.04

    sudo apt update
    sudo install fio
    
  2. Exécutez la commande suivante :

    fio --ioengine=libaio --filesize=32G --ramp_time=2s \
    --runtime=5m --numjobs=16 --direct=1 --verify=0 --randrepeat=0 \
    --group_reporting --directory=/lustre --buffer_compress_percentage=50 \
    --name=read --blocksize=1m --iodepth=64 --readwrite=read
    

L'exécution du test prend environ cinq minutes. Une fois l'opération terminée, les résultats s'affichent. Selon votre configuration, vous pouvez vous attendre à un débit allant jusqu'à la vitesse réseau maximale de votre VM et à des milliers d'IOPS par Tio.

Mesurer les performances d'un multicompte

Pour tester les performances de lecture et d'écriture de Managed Lustre à partir de plusieurs clients Compute Engine, utilisez l'outil de benchmark IOR. Les instructions suivantes vous montrent comment automatiser la configuration de votre client et utiliser IOR pour tester les E/S agrégées de plusieurs machines clientes. IOR utilise MPI, un protocole de transmission de messages, pour permettre aux différentes machines clientes de se coordonner entre elles.

Avant de commencer, assurez-vous que la valeur mtu de votre réseau est définie sur 8896.

Définir des variables d'environnement et générer une clé SSH

Avant de déployer votre cluster, générez une clé SSH sur votre machine locale. Cette clé sera distribuée à vos machines clientes lors de la création pour permettre une communication sans mot de passe pour MPI.

export SSH_USER="lustre-user"
export CLIENT_PREFIX="lustre-client"

# Generate an SSH key for the specified user
ssh-keygen -t rsa -b 4096 -C "${SSH_USER}" -N '' -f "./id_rsa"
chmod 600 "./id_rsa"

# Create a metadata file formatted for Google Cloud
echo "${SSH_USER}:$(cat "./id_rsa.pub") ${SSH_USER}" > "./keys.txt"

Créer le script de démarrage

Enregistrez le contenu suivant dans un fichier nommé install-ior.sh sur votre ordinateur local. Ce script détecte le système d'exploitation, attend la libération des verrous de démarrage, installe en toute sécurité le client Lustre et les dépendances, compile une version stable d'IOR et installe le système de fichiers Lustre géré.

Remplacez LUSTRE_IP par l'adresse IP de votre instance Managed Lustre et FS_NAME par le nom de votre système de fichiers.

#!/bin/bash
source /etc/os-release

if [[ "$ID" == "ubuntu" ]]; then
    # Ubuntu
    # Wait for apt lock
    while fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; do sleep 5; done

    # Configure Artifact Registry repo for Ubuntu
    curl -fsSL https://us-apt.pkg.dev/doc/repo-signing-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/us-apt-pkg-dev.gpg

    if [[ "$VERSION_ID" == "22.04" ]]; then
        REPO_NAME="lustre-client-ubuntu-jammy"
    elif [[ "$VERSION_ID" == "24.04" ]]; then
        REPO_NAME="lustre-client-ubuntu-noble"
    fi

    echo "deb [signed-by=/usr/share/keyrings/us-apt-pkg-dev.gpg] https://us-apt.pkg.dev/projects/lustre-client-binaries $REPO_NAME main" | sudo tee /etc/apt/sources.list.d/lustre-client.list

    sudo apt-get update
    while ! sudo apt-get install -y lustre-client-modules-$(uname -r) lustre-client-utils openmpi-bin libopenmpi-dev make gcc g++ wget git automake autoconf libaio-dev; do
        sleep 5
    done
    sudo modprobe lustre
else
    # Red Hat / Rocky Linux
    while systemctl is-active --quiet dnf-makecache.service; do sleep 5; done

    if [[ "$ID" == "rocky" && "$VERSION_ID" == 8* ]]; then
        REPO="lustre-client-rocky-8"
    elif [[ "$ID" == "rocky" && "$VERSION_ID" == 9* ]]; then
        REPO="lustre-client-rocky-9"
    elif [[ "$ID" == "rhel" && "$VERSION_ID" == 9* ]]; then
        REPO="lustre-client-rocky-9"
    fi

    gcloud beta artifacts print-settings yum --repository=$REPO --location=us --project=lustre-client-binaries | sudo bash

    while ! sudo dnf -y --enablerepo=$REPO install kmod-lustre-client lustre-client; do sleep 5; done
    sudo modprobe lustre

    while ! sudo dnf install -y openmpi openmpi-devel make gcc gcc-c++ wget git automake autoconf libaio-devel; do sleep 5; done

    export PATH=$PATH:/usr/lib64/openmpi/bin
fi

# Build IOR from source
echo "Cloning repo: https://github.com/hpc/ior.git and building IOR"
pushd /tmp
git clone -b 4.0.0 https://github.com/hpc/ior
cd ior
./bootstrap
./configure --disable-dependency-tracking --with-aio
make clean
make -j"$(nproc)"
sudo make install
popd
echo "Finished building IOR"

# Mount the Managed Lustre file system
mkdir -p /lustre

if ! grep -q "/lustre" /etc/fstab; then
    echo "LUSTRE_IP@tcp:/FS_NAME /lustre lustre defaults,_netdev 0 0" >> /etc/fstab
fi

mount -a

Déployer les machines clientes

Exécutez la commande suivante pour créer des machines clientes Compute Engine de manière groupée.

gcloud compute instances bulk create \
  --name-pattern="${CLIENT_PREFIX}-####" \
  --zone="ZONE" \
  --machine-type="MACHINE_TYPE" \
  --scopes="https://www.googleapis.com/auth/cloud-platform" \
  --network-interface=subnet=SUBNET,nic-type=GVNIC \
  --network-performance-configs=total-egress-bandwidth-tier=TIER_1 \
  --metadata-from-file=ssh-keys=./keys.txt,startup-script=install-ior.sh \
  --create-disk=auto-delete=yes,boot=yes,\
image-family=IMAGE_FAMILY,\
image-project=IMAGE_PROJECT,\
mode=rw,size=100,type=DISK_TYPE \
  --count NUM_NODES
  • Remplacez ZONE et SUBNET par les valeurs spécifiques à votre déploiement.

  • Choisissez un MACHINE_TYPE. Les performances globales de votre benchmark dépendent des types de machines clientes. Pour savoir comment choisir des types de machines afin d'obtenir le meilleur débit, consultez Considérations relatives aux performances.

  • Si votre type de machine n'est pas compatible avec le réseau TIER_1, supprimez la ligne --network-performance-configs de la commande.

  • Définissez DISK_TYPE sur hyperdisk-balanced (pour un type de machine avec un 4 dans son nom de génération, tel que c4a ou n4) ou pd-balanced.

  • Spécifiez IMAGE_FAMILY et IMAGE_PROJECT. Valeurs acceptées :

    OS Famille d'images (x86) Famille d'images (ARM) Projet de l'image
    HPC Rocky Linux 8 hpc-rocky-linux-8 Non compatible cloud-hpc-image-public
    Rocky Linux 9 rocky-linux-9 rocky-linux-9-arm64 rocky-linux-cloud
    RHEL 9 rhel-9 rhel-9-arm64 rhel-cloud
    Ubuntu 22.04 LTS ubuntu-2204-lts ubuntu-2204-lts-arm64 ubuntu-os-cloud
    Ubuntu 24.04 LTS Non compatible ubuntu-2404-lts-arm64 ubuntu-os-cloud
  • Spécifiez le NUM_NODES. Pour saturer votre système de fichiers, la capacité réseau globale de votre cluster doit dépasser le débit provisionné de votre système de fichiers d'environ 20%.

    Pour les machines sur lesquelles la mise en réseau Tier 1 est activée, une seule machine peut transférer entre 25 et 200 Gbit/s (environ 3 000 à 25 000 Mbit/s), en fonction de la famille de VM et du nombre de processeurs. Pour les instances standards, le trafic de sortie est généralement limité à environ 2 Gbit/s par vCPU.

    Par exemple, si la capacité de votre instance Managed Lustre génère un débit théorique de 100 000 Mo/s, vous avez besoin d'un trafic de sortie client global de 120 000 Mo/s (100,000 * 1.2) pour la saturer :

    • Avec les instances standards : si chaque machine cliente dispose d'une sortie publiée de 2 000 Mbit/s, vous devez provisionner au moins 60 clients (120,000 / 2,000).
    • Avec la gestion de réseau Tier 1 : si chaque machine cliente dispose d'une sortie publiée de 10 000 MBps (environ 80 Gbit/s), vous devez provisionner au moins 12 clients (120,000 / 10,000).

Copier des clés et des fichiers

Pendant que vous attendez que les machines clientes terminent leurs scripts de démarrage, exécutez les commandes suivantes en local pour configurer automatiquement tous les nœuds pour la communication entre les nœuds.

  1. Enregistrez les adresses IP privées des machines clientes pour le fichier hôte MPI, et les adresses IP publiques pour l'accès SSH et SCP aux machines clientes :

    gcloud compute instances list --filter="name ~ '^${CLIENT_PREFIX}*'" --format="csv[no-heading](INTERNAL_IP)" > hosts.txt
    gcloud compute instances list --filter="name ~ '^${CLIENT_PREFIX}*'" --format="csv[no-heading](EXTERNAL_IP)" > external_ips.txt
    
  2. Copiez la clé privée sur tous les clients. Cela permet aux nœuds de calcul de communiquer entre eux de manière sécurisée pendant le benchmark :

    while IFS= read -r IP || [[ -n "$IP" ]]
    do
      [[ -z "$IP" ]] && continue
      echo "Preparing and copying to ${SSH_USER}@${IP}..."
      # Ensure the .ssh directory exists
      ssh -i ./id_rsa -o StrictHostKeyChecking=no "${SSH_USER}@${IP}" "mkdir -p ~/.ssh && chmod 700 ~/.ssh"
      # Copy the file
      scp -i ./id_rsa -o StrictHostKeyChecking=no ./id_rsa "${SSH_USER}@${IP}:~/.ssh/id_rsa"
    done < "./external_ips.txt"
    
  3. Désignez le nœud principal et copiez-y le fichier d'hôtes. Il s'agit de la machine à partir de laquelle vous exécutez le benchmark.

    export HEAD_NODE=$(head -n 1 ./external_ips.txt)
    scp -i ./id_rsa -o "StrictHostKeyChecking=no" -o UserKnownHostsFile=/dev/null ./hosts.txt ${SSH_USER}@${HEAD_NODE}:~/hostfile
    

Connecter et valider

  1. Connectez-vous à votre nœud principal :

    ssh -i ./id_rsa -o "StrictHostKeyChecking=no" -o UserKnownHostsFile=/dev/null ${SSH_USER}@${HEAD_NODE}
    
  2. Avant d'exécuter le benchmark, vérifiez que le script de démarrage est terminé et que le système de fichiers est correctement installé.

    Pour vérifier les journaux du script de démarrage :

    sudo journalctl -u google-startup-scripts.service -f
    

    Pour vérifier que le système de fichiers est installé :

    df -h | grep lustre
    

    Si le système de fichiers ne figure pas dans la liste, attendez quelques minutes de plus que le script d'installation en arrière-plan se termine. Une fois monté, il sera disponible au chemin d'accès absolu /lustre.

Exécuter le benchmark IOR

  1. Rocky Linux et RHEL uniquement : chargez le module OpenMPI à partir du nœud de tête.

    if [ -f /etc/profile.d/modules.sh ]; then
        source /etc/profile.d/modules.sh
        module load mpi/openmpi-$(arch)
    fi
    
  2. Créez un répertoire de test et devenez-en propriétaire :

    sudo mkdir -p /lustre/test
    sudo chown -R $USER:$USER /lustre/test
    
  3. Définissez les variables de test :

    export NUM_NODES="NUM_NODES"
    export PROCESSES_PER_NODE="PROCESSES_PER_NODE"
    export NUM_PROCESSES=$(( NUM_NODES * PROCESSES_PER_NODE ))
    

    Où :

    • NUM_NODES : nombre total de machines clientes participant au test.
    • PROCESSES_PER_NODE : nombre de rangs MPI à exécuter sur chaque machine cliente individuelle. Nous vous recommandons de commencer par définir ce paramètre sur le nombre de cœurs physiques (ou la moitié du nombre de processeurs virtuels) de vos machines clientes. Pour les types de machines hautes performances, définir cette valeur entre 8 et 16 permet généralement d'obtenir le meilleur débit réseau. Si vous définissez une valeur trop élevée, vous risquez de provoquer une surcharge de changement de contexte et de dégrader les performances du benchmark.
  4. Exécutez la commande pour démarrer le benchmark :

    Rocky Linux et RHEL

    Débit en écriture

    Cette commande écrit en continu pendant 60 secondes pour tester le débit maximal en régime permanent. La taille de fichier par tâche est définie sur un plafond arbitrairement élevé de 50 Tio pour que les tâches continuent d'écrire jusqu'à l'expiration du minuteur de 60 secondes.

    mpirun \
      --allow-run-as-root \
      --mca plm_rsh_no_tree_spawn 1 \
      --mca opal_set_max_sys_limits 1 \
      --mca plm_rsh_num_concurrent ${NUM_NODES} \
      --mca plm_rsh_args "-o StrictHostKeyChecking=no" \
      --prefix /usr/lib64/openmpi \
      --npernode ${PROCESSES_PER_NODE} \
      --np ${NUM_PROCESSES} \
      --hostfile ~/hostfile \
      /usr/local/bin/ior \
      -a AIO \
      --posix.odirect \
      -F -g -v -w -k \
      -t 4m -b 50t \
      -D 60 \
      -O stoneWallingWearOut=1 \
      -O stoneWallingStatusFile=/lustre/test/ior-easy.stonewall \
      -o /lustre/test/ior_file

    Débit en lecture

    Cette phase relit exactement la quantité de données qui a été écrite avec succès lors du test de débit d'écriture de 60 secondes. Bien que la taille de fichier par tâche (-b) soit définie sur 50 Tio pour correspondre à la géométrie de la phase d'écriture, l'indicateur -O stoneWallingWearOut=1 indique à IOR d'arrêter la lecture dès qu'il atteint la limite exacte des données enregistrée dans le fichier d'état stonewall.

    mpirun \
      --allow-run-as-root \
      --mca plm_rsh_no_tree_spawn 1 \
      --mca opal_set_max_sys_limits 1 \
      --mca plm_rsh_num_concurrent ${NUM_NODES} \
      --mca plm_rsh_args "-o StrictHostKeyChecking=no" \
      --prefix /usr/lib64/openmpi \
      --npernode ${PROCESSES_PER_NODE} \
      --np ${NUM_PROCESSES} \
      --hostfile ~/hostfile \
      /usr/local/bin/ior \
      -a AIO \
      --posix.odirect \
      -F -g -v -r -k \
      -t 4m -b 50t \
      -D 60 \
      -O stoneWallingWearOut=1 \
      -O stoneWallingStatusFile=/lustre/test/ior-easy.stonewall \
      -o /lustre/test/ior_file

    IOPS en écriture

    Ce test utilise de petites tailles de transfert de 4 Kio et des tailles de fichier de 8 Gio par tâche pour mesurer le nombre maximal d'opérations d'entrée/sortie par seconde (IOPS) que le système de fichiers peut gérer.

    mpirun \
      --allow-run-as-root \
      --mca plm_rsh_no_tree_spawn 1 \
      --mca opal_set_max_sys_limits 1 \
      --mca plm_rsh_num_concurrent ${NUM_NODES} \
      --mca plm_rsh_args "-o StrictHostKeyChecking=no" \
      --prefix /usr/lib64/openmpi \
      --np ${NUM_PROCESSES} \
      --oversubscribe \
      --map-by node \
      --bind-to socket \
      --hostfile ~/hostfile \
      /usr/local/bin/ior \
      -e \
      -t 4k \
      -b 8g \
      -s 1 \
      -a AIO \
      --posix.odirect \
      --aio.max-pending=256 \
      -w \
      -F \
      -z \
      -Q 1 \
      -G 1745405099 \
      -D 45 \
      -O stoneWallingWearOut=1 \
      -o /lustre/test/ior-random

    IOPS en lecture

    Pour éviter la lecture à partir d'un fichier clairsemé, ce test utilise deux commandes : une écriture pour créer un fichier solide avec des tailles de transfert de 4 Mio et des tailles de fichier de 8 Gio par tâche, suivie du test IOPS de lecture aléatoire de 4 Kio.

    1. Créez le fichier à lire :

      mpirun \
        --allow-run-as-root \
        --mca plm_rsh_no_tree_spawn 1 \
        --mca opal_set_max_sys_limits 1 \
        --mca plm_rsh_num_concurrent ${NUM_NODES} \
        --mca plm_rsh_args "-o StrictHostKeyChecking=no" \
        --prefix /usr/lib64/openmpi \
        --npernode ${PROCESSES_PER_NODE} \
        --np ${NUM_PROCESSES} \
        --oversubscribe \
        --map-by node \
        --bind-to socket \
        --hostfile ~/hostfile \
        /usr/local/bin/ior \
        -a AIO \
        --posix.odirect \
        -w \
        -F \
        -k \
        -t 4m \
        -b 8g \
        -s 1 \
        -Q 1 \
        -G 1745405099 \
        -o /lustre/test/ior_rand_read
    2. Exécutez le test de lecture IOR :

      mpirun \
        --allow-run-as-root \
        --mca plm_rsh_no_tree_spawn 1 \
        --mca opal_set_max_sys_limits 1 \
        --mca plm_rsh_num_concurrent ${NUM_NODES} \
        --mca plm_rsh_args "-o StrictHostKeyChecking=no" \
        --prefix /usr/lib64/openmpi \
        --oversubscribe \
        --map-by node \
        --bind-to socket \
        --npernode ${PROCESSES_PER_NODE} \
        --np ${NUM_PROCESSES} \
        --hostfile ~/hostfile \
        /usr/local/bin/ior \
        -a AIO \
        --posix.odirect \
        --aio.max-pending 256 \
        -r \
        -F \
        -z \
        -t 4k \
        -b 8g \
        -s 1 \
        -Q 1 \
        -G 1745405099 \
        -D 45 \
        -O stoneWallingWearOut=1 \
        -o /lustre/test/ior_rand_read

    Ubuntu

    Débit en écriture

    Cette commande écrit en continu pendant 60 secondes pour tester le débit maximal en régime permanent. La taille de fichier par tâche est définie sur un plafond arbitrairement élevé de 50 Tio pour que les tâches continuent d'écrire jusqu'à l'expiration du minuteur de 60 secondes.

    mpirun \
      --allow-run-as-root \
      --mca plm_rsh_no_tree_spawn 1 \
      --mca opal_set_max_sys_limits 1 \
      --mca plm_rsh_num_concurrent ${NUM_NODES} \
      --mca plm_rsh_args "-o StrictHostKeyChecking=no" \
      --npernode ${PROCESSES_PER_NODE} \
      --np ${NUM_PROCESSES} \
      --hostfile ~/hostfile \
      /usr/local/bin/ior \
      -a AIO \
      --posix.odirect \
      -F -g -v -w -k \
      -t 4m -b 50t \
      -D 60 \
      -O stoneWallingWearOut=1 \
      -O stoneWallingStatusFile=/lustre/test/ior-easy.stonewall \
      -o /lustre/test/ior_file

    Débit en lecture

    Cette phase relit exactement la quantité de données qui a été écrite avec succès lors du test de débit d'écriture de 60 secondes. Bien que la taille de fichier par tâche (-b) soit définie sur 50 Tio pour correspondre à la géométrie de la phase d'écriture, l'indicateur -O stoneWallingWearOut=1 indique à IOR d'arrêter la lecture dès qu'il atteint la limite exacte des données enregistrée dans le fichier d'état stonewall.

    mpirun \
      --allow-run-as-root \
      --mca plm_rsh_no_tree_spawn 1 \
      --mca opal_set_max_sys_limits 1 \
      --mca plm_rsh_num_concurrent ${NUM_NODES} \
      --mca plm_rsh_args "-o StrictHostKeyChecking=no" \
      --npernode ${PROCESSES_PER_NODE} \
      --np ${NUM_PROCESSES} \
      --hostfile ~/hostfile \
      /usr/local/bin/ior \
      -a AIO \
      --posix.odirect \
      -F -g -v -r -k \
      -t 4m -b 50t \
      -D 60 \
      -O stoneWallingWearOut=1 \
      -O stoneWallingStatusFile=/lustre/test/ior-easy.stonewall \
      -o /lustre/test/ior_file

    IOPS en écriture

    Ce test utilise de petites tailles de transfert de 4 Kio et des tailles de fichier de 8 Gio par tâche pour mesurer le nombre maximal d'opérations d'entrée/sortie par seconde (IOPS) que le système de fichiers peut gérer.

    mpirun \
      --allow-run-as-root \
      --mca plm_rsh_no_tree_spawn 1 \
      --mca opal_set_max_sys_limits 1 \
      --mca plm_rsh_num_concurrent ${NUM_NODES} \
      --mca plm_rsh_args "-o StrictHostKeyChecking=no" \
      --np ${NUM_PROCESSES} \
      --oversubscribe \
      --map-by node \
      --bind-to socket \
      --hostfile ~/hostfile \
      /usr/local/bin/ior \
      -e \
      -t 4k \
      -b 8g \
      -s 1 \
      -a AIO \
      --posix.odirect \
      --aio.max-pending=256 \
      -w \
      -F \
      -z \
      -Q 1 \
      -G 1745405099 \
      -D 45 \
      -O stoneWallingWearOut=1 \
      -o /lustre/test/ior-random

    IOPS en lecture

    Pour éviter la lecture à partir d'un fichier clairsemé, ce test utilise deux commandes : une écriture pour créer un fichier solide avec des tailles de transfert de 4 Mio et des tailles de fichier de 8 Gio par tâche, suivie du test IOPS de lecture aléatoire de 4 Kio.

    1. Créez le fichier à lire :

      mpirun \
        --allow-run-as-root \
        --mca plm_rsh_no_tree_spawn 1 \
        --mca opal_set_max_sys_limits 1 \
        --mca plm_rsh_num_concurrent ${NUM_NODES} \
        --mca plm_rsh_args "-o StrictHostKeyChecking=no" \
        --npernode ${PROCESSES_PER_NODE} \
        --np ${NUM_PROCESSES} \
        --oversubscribe \
        --map-by node \
        --bind-to socket \
        --hostfile ~/hostfile \
        /usr/local/bin/ior \
        -a AIO \
        --posix.odirect \
        -w \
        -F \
        -k \
        -t 4m \
        -b 8g \
        -s 1 \
        -Q 1 \
        -G 1745405099 \
        -o /lustre/test/ior_rand_read
    2. Exécutez le test de lecture IOR :

      mpirun \
        --allow-run-as-root \
        --mca plm_rsh_no_tree_spawn 1 \
        --mca opal_set_max_sys_limits 1 \
        --mca plm_rsh_num_concurrent ${NUM_NODES} \
        --mca plm_rsh_args "-o StrictHostKeyChecking=no" \
        --oversubscribe \
        --map-by node \
        --bind-to socket \
        --npernode ${PROCESSES_PER_NODE} \
        --np ${NUM_PROCESSES} \
        --hostfile ~/hostfile \
        /usr/local/bin/ior \
        -a AIO \
        --posix.odirect \
        --aio.max-pending 256 \
        -r \
        -F \
        -z \
        -t 4k \
        -b 8g \
        -s 1 \
        -Q 1 \
        -G 1745405099 \
        -D 45 \
        -O stoneWallingWearOut=1 \
        -o /lustre/test/ior_rand_read

    Les options mpirun sont les suivantes :

    • --mca plm_rsh_no_tree_spawn 1 : désactive la création de daemons basés sur un arbre pour améliorer la fiabilité du lancement sur les nœuds.
    • --mca opal_set_max_sys_limits 1 : tente automatiquement de définir les limites du système (comme le nombre maximal de fichiers ouverts) sur leurs valeurs maximales autorisées.
    • --mca plm_rsh_num_concurrent : définit le nombre maximal de connexions SSH simultanées que mpirun utilisera lors du lancement des daemons de nœud de calcul.
    • --mca plm_rsh_args ... : contourne la vérification stricte des clés d'hôte pour empêcher les invites SSH interactives de bloquer le lancement du processus MPI.
    • --prefix ... : définit explicitement le chemin d'installation d'OpenMPI pour Rocky Linux et RHEL afin que les nœuds de calcul puissent trouver le démon requis (orted).
    • --allow-run-as-root : permet à mpirun de s'exécuter en tant qu'utilisateur racine.
    • --oversubscribe : permet à MPI de planifier plus de processus sur un nœud qu'il n'y a de cœurs physiques disponibles.
    • --map-by node : distribue les processus MPI de manière séquentielle et uniforme sur les nœuds disponibles.
    • --bind-to socket : lie les processus MPI aux sockets de processeur physiques pour optimiser l'accès à la mémoire et les performances du cache.
    • --npernode : nombre de processus par nœud.
    • --np : nombre total de processus MPI à lancer.
    • --hostfile : spécifie le fichier contenant la liste des hôtes sur lesquels exécuter le test.

    Les options ior sont les suivantes :

    • -a AIO --posix.odirect : utilise le moteur d'E/S asynchrones (AIO) combiné aux E/S directes POSIX. Cela contourne le cache de pages RAM côté client et force les écritures simultanées non bloquantes directement sur les serveurs de stockage, ce qui garantit que le benchmark mesure les performances réelles du stockage réseau plutôt que les tampons de mémoire.
    • --aio.max-pending=256 : détermine le nombre maximal d'opérations d'E/S asynchrones simultanées en cours par processus.
    • -C : réorganisez les tâches pour optimiser les performances de lecture.
    • -F : mode "un fichier par processus".
    • -g : utilisez des barrières pour séparer les phases d'écriture et de lecture du test.
    • -v : affiche la journalisation détaillée.
    • -w / -r : indique à IOR d'exécuter le test de performances d'écriture (-w) ou de lecture (-r).
    • -k : empêche IOR de supprimer le fichier de test après l'écriture, ce qui le rend disponible pour le test de lecture.
    • -e : effectue un fsync après la phase d'écriture pour garantir que les données sont validées sur les lecteurs de stockage.
    • -z : indique à IOR d'effectuer des E/S à accès aléatoire plutôt qu'à accès séquentiel.
    • -s 1 : définit le nombre de segments sur 1.
    • -Q 1 : définit le décalage des tâches par nœud, en alignant les tâches afin que le benchmark se coordonne correctement sur tous les nœuds.
    • -G 1745405099 : code en dur le code temporel de la graine aléatoire afin que la phase de lecture génère exactement les mêmes décalages de fichier aléatoires que ceux utilisés par la phase d'écriture.
    • -t : définit la taille du transfert pour chaque opération d'E/S (par exemple, 4m pour le débit, 4k pour les IOPS).
    • -b : définit la taille de bloc cible par processus (par exemple, 50t pour le débit, 8g pour les IOPS) afin de s'assurer que le test ne manque pas de données utiles pendant l'exécution chronométrée.
    • -D : limite la durée d'exécution du test à un nombre spécifique de secondes (par exemple, 60 ou 45). Cette "stonewalling" met fin au benchmark de manière uniforme pour capturer une véritable mesure à l'état stable.
    • -O stoneWallingWearOut=1 : force tous les threads simultanés à continuer à générer une charge d'écriture continue pendant toute la durée, ce qui empêche les threads plus rapides de se terminer plus tôt et de réduire la pression globale sur le réseau.
    • -O stoneWallingStatusFile=<path> : écrit un fichier de validation de l'état à la fin de la phase d'écriture. La phase de lecture suivante utilise ce fichier pour lire uniquement les blocs qui ont été validés avec succès, ce qui évite les erreurs de pointeur null lors des lectures.
    • -o : chemin d'accès au fichier de test sur le système de fichiers Managed Lustre.

Afficher les résultats

Une fois le benchmark terminé, il affiche les métriques de performances globales de toutes les VM ou de tous les pods clients directement dans votre terminal. Recherchez le tableau Résultats en bas de la sortie pour trouver votre débit ou vos IOPS maximums.

Métriques clés

  • aggregate filesize : quantité totale de données écrites ou lues pendant le test sur tous les clients participants.

  • bw(MiB/s) / Max Write / Max Read : métrique la plus importante pour les tests séquentiels. Elle indique la bande passante globale obtenue par le système de fichiers Lustre géré.

  • IOPS : métrique la plus importante pour les tests d'E/S aléatoires. Il indique le nombre maximal d'opérations d'entrée/sortie par seconde.

Exporter les résultats vers un fichier

Si vous souhaitez analyser vos résultats de manière programmatique, les insérer dans une base de données ou les enregistrer pour une analyse ultérieure, vous pouvez demander à IOR d'exporter les données récapitulatives aux formats JSON et CSV au lieu de simplement les afficher à l'écran.

Pour ce faire, ajoutez les indicateurs -O à la fin de la chaîne de commande ior :

-O summaryFormat=JSON \
-O summaryFile=/lustre/test/perf-results/summary.json \
-O saveRankPerformanceDetailsCSV=/lustre/test/perf-results/details.csv

Le répertoire de sortie doit exister sur le système de fichiers avant l'exécution du benchmark.

Performances attendues par rapport aux performances réelles

Vous pouvez calculer le débit maximal mathématique de votre système de fichiers en fonction de sa capacité provisionnée et de son niveau de performances. Étant donné que la capacité de stockage est provisionnée en gibioctets (Gio) et que les niveaux sont évalués en tébioctets (Tio), vous devez d'abord convertir votre capacité :

(Capacity GiB/1 024) * Tier MBps = Mbit/s théorique max

Par exemple, une instance de 216 000 Gio dans le niveau 500 Mbit/s par Tio fournit mathématiquement un débit de 105 469 Mbit/s ((216 000/1 024) * 500).

Le débit maximal observé sera toujours limité par la capacité de débit provisionnée de votre système de fichiers ou par les limites de sortie réseau combinées de vos machines clientes, selon la valeur la plus basse.

Voici quelques raisons courantes pour lesquelles vos chiffres de référence peuvent ne pas atteindre les vitesses théoriques :

  • Surcharge TCP/IP : l'encapsulation réseau standard et les en-têtes de paquets consomment environ 5 à 10% de la bande passante brute. Votre maximum mathématique inclut ce coût, mais le benchmark IOR ne mesure que la charge utile brute écrite sur le disque.

  • Limites du réseau client : les machines clientes sont soumises à des limites strictes de bande passante de sortie. Si vous utilisez un petit nombre de clients ou de nœuds, ou des types de machines sans réseau de niveau 1 activé, les clients limiteront le benchmark avant que le système de fichiers Managed Lustre n'atteigne sa limite.

  • Changement de contexte MPI : si PROCESSES_PER_NODE est défini sur une valeur supérieure au nombre de cœurs physiques de vos machines clientes, la contention du processeur et la surcharge de changement de contexte dégraderont artificiellement les performances d'E/S du benchmark.

  • E/S directes manquantes : si l'indicateur --posix.odirect est omis, les données transitent par le cache de pages RAM du client. Cela introduit des goulots d'étranglement de la mémoire et une surcharge du processeur qui masquent les véritables performances de stockage réseau.

Effectuer un nettoyage

Pour éviter que les ressources utilisées sur cette page ne soient facturées sur votre compte Google Cloud , procédez comme suit :

  1. Supprimez les fichiers de test du volume Managed Lustre :

    ssh -i ./id_rsa -o "StrictHostKeyChecking=no" -o UserKnownHostsFile=/dev/null ${SSH_USER}@${HEAD_NODE} "rm -rf /lustre/test"
    
  2. Supprimez les machines clientes Compute Engine créées de manière groupée :

    gcloud compute instances delete $(gcloud compute instances list \
      --filter="name~'^${CLIENT_PREFIX}-'" --format="value(name)" --zones="ZONE") \
      --zone="ZONE"
    

    Vous pouvez également supprimer les noms exacts ou les supprimer individuellement :

    gcloud compute instances delete CLIENT_PREFIX-0001 CLIENT_PREFIX-0002 ... --zone=ZONE
    
  3. Si vous avez créé une image personnalisée, vous pouvez la supprimer :

    gcloud compute images delete CUSTOM_IMAGE_NAME
    
  4. Si vous avez créé l'instance Managed Lustre spécifiquement pour ce test et que vous n'en avez plus besoin, supprimez-la :

    gcloud lustre instances delete INSTANCE_ID --location=LOCATION
    

Résoudre les problèmes courants de goulots d'étranglement liés aux tests de performances

Si les résultats de votre benchmark sont nettement inférieurs au niveau de performances de stockage attendu, consultez Résoudre les problèmes de goulots d'étranglement courants.