Auf dieser Seite wird beschrieben, wie Sie die Leistung einer verwalteten Google Cloud Managed Lustre-Instanz mit Compute Engine-Clients testen. Außerdem finden Sie hier eine Anleitung zum Messen der Leistung eines einzelnen Clients mit fio und der aggregierten Leistung mehrerer Clients mit dem IOR-Benchmark-Tool.
Leistung eines einzelnen Clients messen
Verwenden Sie
das fio (Flexible I/O tester) Befehlszeilentool, um die Lese- und Schreibleistung eines einzelnen Compute Engine-Clients zu testen.
Installieren Sie fio:
Rocky 8
sudo dnf install fio -yUbuntu 20.04 und 22.04
sudo apt update sudo install fioFühren Sie dazu diesen Befehl aus:
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
Der Test dauert etwa 5 Minuten. Nach Abschluss werden die Ergebnisse angezeigt. Je nach Konfiguration können Sie einen Durchsatz von bis zu Ihrer VM's maximalen Netzwerkgeschwindigkeit und Tausende von IOPS pro TiB erwarten.
Leistung mehrerer Clients messen
Verwenden Sie das IOR-Benchmark-Tool, um die Lese- und Schreibleistung von Managed Lustre von mehreren Compute Engine-Clients aus zu testen. In der folgenden Anleitung wird beschrieben, wie Sie die Clienteinrichtung automatisieren und mit IOR die aggregierte E/A von mehreren Clientcomputern testen. IOR verwendet MPI, ein Message-Passing-Protokoll, damit die mehreren Clientcomputer miteinander kommunizieren können.
Prüfen Sie vor Beginn, ob der Wert mtu Ihres Netzwerks
auf 8896 festgelegt ist.
Umgebungsvariablen festlegen und SSH-Schlüssel generieren
Generieren Sie vor der Bereitstellung Ihres Clusters einen SSH-Schlüssel auf Ihrem lokalen Computer. Dieser Schlüssel wird während der Erstellung an Ihre Clientcomputer verteilt, um die passwortlose Kommunikation für MPI zu ermöglichen.
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"
Startskript erstellen
Speichern Sie den folgenden Inhalt auf Ihrem lokalen Computer in einer Datei mit dem Namen install-ior.sh. Dieses Skript erkennt das Betriebssystem, wartet, bis die Boot-Locks freigegeben werden, installiert sicher den Lustre-Client und die Abhängigkeiten, kompiliert eine stabile Version von IOR und stellt das Managed Lustre-Dateisystem bereit.
Ersetzen Sie LUSTRE_IP durch die IP-Adresse Ihrer Managed Lustre Instanz und FS_NAME durch den Namen Ihres Dateisystems.
#!/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
Clientcomputer bereitstellen
Führen Sie den folgenden Befehl aus, um die Compute Engine-Clientcomputer im Bulk zu erstellen.
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
Ersetzen Sie ZONE und SUBNET durch die Werte für Ihre Bereitstellung.
Wählen Sie einen MACHINE_TYPE aus. Die Gesamtleistung Ihres Benchmarks hängt von den Maschinentypen der Clients ab. Informationen zur Auswahl von Maschinentypen für den besten Durchsatz finden Sie unter Leistungsüberlegungen.
Wenn Ihr Maschinentyp das TIER_1-Netzwerk nicht unterstützt, löschen Sie die Zeile
--network-performance-configsaus dem Befehl.Legen Sie DISK_TYPE auf einen der folgenden Werte fest:
hyperdisk-balanced(für einen Maschinen typ mit einer4im Namen der Generation, z. B.c4aodern4) oderpd-balanced.Geben Sie IMAGE_FAMILY und IMAGE_PROJECT an. Unterstützte Werte sind:
Betriebssystem Image-Familie (x86) Image-Familie (ARM) Image-Projekt HPC Rocky Linux 8 hpc-rocky-linux-8Nicht unterstützt cloud-hpc-image-publicRocky Linux 9 rocky-linux-9rocky-linux-9-arm64rocky-linux-cloudRHEL 9 rhel-9rhel-9-arm64rhel-cloudUbuntu 22.04 LTS ubuntu-2204-ltsubuntu-2204-lts-arm64ubuntu-os-cloudUbuntu 24.04 LTS Nicht unterstützt ubuntu-2404-lts-arm64ubuntu-os-cloudGeben Sie NUM_NODES an. Um Ihr Dateisystem zu sättigen, sollte die aggregierte Netzwerkkapazität Ihres Clusters den bereitgestellten Durchsatz Ihres Dateisystems um etwa 20 % übersteigen.
Bei Maschinen mit aktiviertem Tier 1-Netzwerk kann eine einzelne Maschine je nach VM-Familie und Anzahl der CPUs zwischen 25 Gbit/s und 200 Gbit/s (~3.000–25.000 MB/s) übertragen. Bei Standardinstanzen ist der ausgehende Traffic in der Regel auf etwa 2 Gbit/s pro vCPU begrenzt.
Wenn die Kapazität Ihrer Managed Lustre-Instanz beispielsweise einen theoretischen Durchsatz von 100.000 MB/s ergibt, benötigen Sie einen aggregierten ausgehenden Traffic von 120.000 MB/s (
100,000 * 1.2), um sie zu sättigen:- Mit Standardinstanzen: Wenn jede Clientmaschine einen veröffentlichten ausgehenden Traffic
von 2.000 MB/s hat, sollten Sie mindestens 60 Clients bereitstellen (
120,000 / 2,000). - Mit Tier 1-Netzwerk: Wenn jede Clientmaschine einen veröffentlichten ausgehenden Traffic von
10.000 MB/s (~80 Gbit/s) hat, sollten Sie mindestens 12 Clients bereitstellen
(
120,000 / 10,000).
- Mit Standardinstanzen: Wenn jede Clientmaschine einen veröffentlichten ausgehenden Traffic
von 2.000 MB/s hat, sollten Sie mindestens 60 Clients bereitstellen (
Schlüssel und Dateien kopieren
Während Sie warten, bis die Startskripts der Clientcomputer abgeschlossen sind, führen Sie die folgenden Befehle lokal aus, um alle Knoten automatisch für die Kommunikation zwischen Knoten zu konfigurieren.
Speichern Sie die privaten IP-Adressen der Clientcomputer für die MPI-Hostdatei und die öffentlichen IP-Adressen für den SSH- und SCP-Zugriff auf die Clientcomputer:
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.txtKopieren Sie den privaten Schlüssel auf alle Clients. So können die Worker-Knoten während des Benchmarks sicher miteinander kommunizieren:
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"Weisen Sie den Hauptknoten zu und kopieren Sie die Hostdatei darauf. Dies ist der Computer, auf dem Sie den Benchmark ausführen.
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
Verbindung herstellen und prüfen
Stellen Sie eine Verbindung zu Ihrem Hauptknoten her:
ssh -i ./id_rsa -o "StrictHostKeyChecking=no" -o UserKnownHostsFile=/dev/null ${SSH_USER}@${HEAD_NODE}Prüfen Sie, ob das Startskript abgeschlossen ist und das Dateisystem erfolgreich bereitgestellt wurde, bevor Sie den Benchmark ausführen.
So prüfen Sie die Startskript-Logs:
sudo journalctl -u google-startup-scripts.service -fSo prüfen Sie, ob das Dateisystem bereitgestellt ist:
df -h | grep lustreWenn das Dateisystem nicht aufgeführt ist, warten Sie einige Minuten, bis das Hintergrundinstallationsskript abgeschlossen ist. Nach der Bereitstellung ist es unter dem absoluten Pfad
/lustreverfügbar.
IOR-Benchmark ausführen
Nur Rocky Linux und RHEL:Laden Sie das OpenMPI-Modul vom Hauptknoten.
if [ -f /etc/profile.d/modules.sh ]; then source /etc/profile.d/modules.sh module load mpi/openmpi-$(arch) fiErstellen Sie ein Testverzeichnis und übernehmen Sie die Inhaberschaft:
sudo mkdir -p /lustre/test sudo chown -R $USER:$USER /lustre/testDefinieren Sie Testvariablen:
export NUM_NODES="NUM_NODES" export PROCESSES_PER_NODE="PROCESSES_PER_NODE" export NUM_PROCESSES=$(( NUM_NODES * PROCESSES_PER_NODE ))Wobei:
- NUM_NODES: Die Gesamtzahl der Clientcomputer, die am Test teilnehmen.
- PROCESSES_PER_NODE: Die Anzahl der MPI-Ränge, die auf jeder
einzelnen Clientmaschine ausgeführt werden sollen. Wir empfehlen, diesen Wert zu Beginn auf die Anzahl der physischen Kerne (oder die Hälfte der Anzahl der vCPUs) auf Ihren Clientcomputern festzulegen. Bei leistungsstarken Maschinentypen ergibt sich in der Regel der beste Netzwerkdurchsatz, wenn dieser Wert zwischen
8und16liegt. Wenn Sie diesen Wert zu hoch festlegen, kann dies zu Overhead beim Kontextwechsel führen und die Benchmark-Leistung beeinträchtigen.
Führen Sie den Befehl aus, um den Benchmark zu starten:
Rocky Linux und RHEL
Durchsatz für Schreibvorgänge
Dieser Befehl schreibt 60 Sekunden lang kontinuierlich, um den maximalen Durchsatz im stabilen Zustand zu testen. Die Dateigröße pro Aufgabe ist auf ein beliebig großes Limit von 50 TiB festgelegt, damit Aufgaben so lange geschrieben werden, bis der 60-Sekunden-Timer abläuft.
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
Durchsatz für Lesevorgänge
In dieser Phase wird genau die Datenmenge zurückgelesen, die während des 60-Sekunden-Tests zum Durchsatz für Schreibvorgänge erfolgreich geschrieben wurde. Obwohl die Dateigröße pro Aufgabe (
-b) auf 50 TiB festgelegt ist, um der Geometrie der Schreibphase zu entsprechen, weist das Flag-O stoneWallingWearOut=1IOR an, das Lesen zu beenden, sobald die genaue Datengrenze erreicht ist, die in der Stonewall-Statusdatei aufgezeichnet wurde.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
Schreib-IOPS
Bei diesem Test werden kleine Übertragungsgrößen von 4 KiB und Dateigrößen von 8 GiB pro Aufgabe verwendet, um die maximale Anzahl von Eingabe-/Ausgabevorgängen pro Sekunde (IOPS) zu messen, die das Dateisystem verarbeiten kann.
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
Lese-IOPS
Um zu verhindern, dass aus einer spärlichen Datei gelesen wird, werden bei diesem Test zwei Befehle verwendet: Ein Schreibvorgang zum Erstellen einer soliden Datei mit Übertragungsgrößen von 4 MiB und Dateigrößen von 8 GiB pro Aufgabe, gefolgt vom eigentlichen 4-KiB-Test für zufällige Lese-IOPS.
Erstellen Sie die zu lesende Datei:
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
Führen Sie den IOR-Lesetest aus:
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
Durchsatz für Schreibvorgänge
Dieser Befehl schreibt 60 Sekunden lang kontinuierlich, um den maximalen Durchsatz im stabilen Zustand zu testen. Die Dateigröße pro Aufgabe ist auf ein beliebig großes Limit von 50 TiB festgelegt, damit Aufgaben so lange geschrieben werden, bis der 60-Sekunden-Timer abläuft.
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
Durchsatz für Lesevorgänge
In dieser Phase wird genau die Datenmenge zurückgelesen, die während des 60-Sekunden-Tests zum Durchsatz für Schreibvorgänge erfolgreich geschrieben wurde. Obwohl die Dateigröße pro Aufgabe (
-b) auf 50 TiB festgelegt ist, um der Geometrie der Schreibphase zu entsprechen, weist das Flag-O stoneWallingWearOut=1IOR an, das Lesen zu beenden, sobald die genaue Datengrenze erreicht ist, die in der Stonewall-Statusdatei aufgezeichnet wurde.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
Schreib-IOPS
Bei diesem Test werden kleine Übertragungsgrößen von 4 KiB und Dateigrößen von 8 GiB pro Aufgabe verwendet, um die maximale Anzahl von Eingabe-/Ausgabevorgängen pro Sekunde (IOPS) zu messen, die das Dateisystem verarbeiten kann.
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
Lese-IOPS
Um zu verhindern, dass aus einer spärlichen Datei gelesen wird, werden bei diesem Test zwei Befehle verwendet: Ein Schreibvorgang zum Erstellen einer soliden Datei mit Übertragungsgrößen von 4 MiB und Dateigrößen von 8 GiB pro Aufgabe, gefolgt vom eigentlichen 4-KiB-Test für zufällige Lese-IOPS.
Erstellen Sie die zu lesende Datei:
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
Führen Sie den IOR-Lesetest aus:
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
Die
mpirun-Flags sind:--mca plm_rsh_no_tree_spawn 1: Deaktiviert das baumbasierte Erstellen von Daemons, um die Zuverlässigkeit des Starts auf allen Knoten zu verbessern.--mca opal_set_max_sys_limits 1: Versucht automatisch, System limits (z. B. die maximale Anzahl offener Dateien) auf die höchstzulässigen Werte festzulegen.--mca plm_rsh_num_concurrent: Legt die maximale Anzahl gleichzeitiger SSH Verbindungen fest, diempirunbeim Starten von Worker-Daemons verwendet.--mca plm_rsh_args ...: Umgeht die strenge Prüfung des Hostschlüssels, um zu verhindern, dass interaktive SSH-Aufforderungen den Start des MPI-Prozesses aufhängen.--prefix ...: Definiert explizit den OpenMPI-Installationspfad für Rocky Linux und RHEL, damit Worker-Knoten den erforderlichen Daemon (orted) finden können.--allow-run-as-root: Ermöglicht die Ausführung vonmpirunals Root-Nutzer.--oversubscribe: Ermöglicht MPI, mehr Prozesse auf einem Knoten zu planen, als physische Kerne verfügbar sind.--map-by node: Verteilt MPI-Prozesse im Round-Robin-Verfahren gleichmäßig auf die verfügbaren Knoten.--bind-to socket: Bindet MPI-Prozesse an physische CPU-Sockets, um den Speicherzugriff und die Cacheleistung zu optimieren.--npernode: Die Anzahl der Prozesse pro Knoten.--np: Die Gesamtzahl der zu startenden MPI-Prozesse.--hostfile: Gibt die Datei mit der Liste der Hosts an, auf denen der Benchmark ausgeführt werden soll.
Die
ior-Flags sind:-a AIO --posix.odirect: Verwendet die Asynchronous I/O (AIO)-Engine in Kombination mit POSIX Direct I/O. Dadurch wird der RAM-Seitencache auf der Clientseite umgangen und gleichzeitige nicht blockierende Schreibvorgänge werden direkt auf die Speicherserver erzwungen. So wird mit dem Benchmark die tatsächliche Leistung des Netzwerkspeichers und nicht die Leistung von Arbeitsspeicherpuffern gemessen.--aio.max-pending=256: Bestimmt die maximale Anzahl gleichzeitiger asynchroner E/A-Vorgänge pro Prozess.-C: Ordnet Aufgaben neu an, um die Leseleistung zu optimieren.-F: Modus „Datei pro Prozess“.-g: Verwendet Barrieren, um die Schreib- und Lesephasen des Tests zu trennen.-v: Gibt ausführliche Logs aus.-w/-r: Weist IOR an, den Leistungstest für Schreibvorgänge (-w) oder Lesevorgänge (-r) auszuführen.-k: Verhindert, dass IOR die Testdatei nach dem Schreiben löscht, sodass sie für den Lesetest verfügbar ist.-e: Führt nach der Schreibphase einenfsync-Vorgang aus, um sicherzustellen, dass die Daten auf die Speicherlaufwerke übertragen werden.-z: Weist IOR an, zufällige E/A-Vorgänge anstelle von sequenziellen Zugriffen auszuführen.-s 1: Legt die Anzahl der Segmente auf 1 fest.-Q 1: Legt den Offset für die Aufgabe pro Knoten fest und richtet Aufgaben so aus, dass der Benchmark auf allen Knoten korrekt koordiniert wird.-G 1745405099: Codiert den Zeitstempel für den Zufallssamen fest, sodass in der Lesevorgangsphase genau dieselben zufälligen Datei-Offsets generiert werden, die in der Schreibvorgangsphase verwendet wurden.-t: Legt die Übertragungsgröße für jeden E/A-Vorgang fest (z.B.4mfür den Durchsatz,4kfür IOPS).-b: Legt die Zielblockgröße pro Prozess fest (z.B.50tfür den Durchsatz,8gfür IOPS), um sicherzustellen, dass während der zeitgesteuerten Ausführung nicht die Nutzdaten ausgehen.-D: Beschränkt die Laufzeit des Tests auf eine bestimmte Anzahl von Sekunden (z.B.60oder45). Durch diese „Stonewalling“-Methode wird der Benchmark gleichmäßig beendet, um eine echte Messung im stabilen Zustand zu erfassen.-O stoneWallingWearOut=1: Erzwingt, dass alle gleichzeitigen Threads die gesamte Dauer über kontinuierlich Schreiblast generieren, wodurch verhindert wird, dass schnellere Threads frühzeitig abgeschlossen werden und der Gesamtdruck auf das Netzwerk sinkt.-O stoneWallingStatusFile=<path>: Schreibt am Ende der Schreibphase eine Statusprüfungsdatei. In der nachfolgenden Lesevorgangsphase werden mit dieser Datei nur die Blöcke gelesen, die erfolgreich übertragen wurden, wodurch Nullzeigerfehler beim Lesen verhindert werden.-o: Der Pfad zur Testdatei im Managed Lustre Dateisystem.
Ergebnisse aufrufen
Nach Abschluss des Benchmarks werden die aggregierten Leistungsmesswerte aller Client-VMs oder -Pods direkt im Terminal angezeigt. In der Tabelle Results unten in der Ausgabe finden Sie den maximalen Durchsatz oder die maximale Anzahl von IOPS.
Wichtige Messwerte
aggregate filesize: Die Gesamtmenge der Daten, die während des Tests auf allen beteiligten Clients geschrieben oder gelesen wurden.bw(MiB/s)/Max Write/Max Read: Der wichtigste Messwert für sequenzielle Tests. Hier wird die aggregierte Bandbreite angezeigt, die vom Managed Lustre-Dateisystem erreicht wurde.IOPS: Der wichtigste Messwert für zufällige E/A-Tests. Hier wird die maximale Anzahl von Eingabe-/Ausgabevorgängen pro Sekunde angezeigt.
Ergebnisse in eine Datei exportieren
Wenn Sie Ihre Ergebnisse programmatisch parsen, in eine Datenbank einfügen oder für eine spätere Analyse speichern möchten, können Sie IOR anweisen, die Zusammenfassungsdaten im JSON- und CSV-Format zu exportieren, anstatt sie nur auf dem Bildschirm auszugeben.
Fügen Sie dazu die -O-Flags am Ende der ior-Befehlszeile an:
-O summaryFormat=JSON \
-O summaryFile=/lustre/test/perf-results/summary.json \
-O saveRankPerformanceDetailsCSV=/lustre/test/perf-results/details.csv
Das Ausgabeverzeichnis muss im Dateisystem vorhanden sein, bevor Sie den Benchmark ausführen.
Erwartete Leistung im Vergleich zur tatsächlichen Leistung
Sie können den mathematischen maximalen Durchsatz Ihres Dateisystems anhand der bereitgestellten Kapazität und der Leistungsstufe berechnen. Da die Speicherkapazität in Gibibyte (GiB) bereitgestellt wird und die Stufen in Tebibyte (TiB) angegeben werden, müssen Sie zuerst die Kapazität umrechnen:
(Capacity GiB / 1024) * Tier MBps = Theoretisches Maximum in MB/s
Eine 216.000 GiB -Instanz in der Stufe 500 MB/s pro TiB bietet mathematisch beispielsweise einen Durchsatz von 105.469 MB/s ((216000 / 1024) * 500).
Der maximal beobachtete Durchsatz ist immer durch den bereitgestellten Durchsatz Ihres Dateisystems oder die kombinierten Limits für ausgehenden Traffic Ihrer Clientcomputer begrenzt, je nachdem, welcher Wert niedriger ist.
Häufige Gründe dafür, dass Ihre Benchmark-Zahlen nicht die theoretischen Geschwindigkeiten erreichen:
TCP/IP-Overhead:Standardmäßige Netzwerkkapselung und Paketheader verbrauchen etwa 5–10% der Rohbandbreite. Ihr mathematisches Maximum umfasst diesen Aufwand, aber der IOR-Benchmark misst nur die Rohdaten-Nutzlast, die auf das Laufwerk geschrieben wird.
Netzwerklimitierungen des Clients:Clientcomputer haben strenge Limits für ausgehenden Traffic. Wenn Sie eine kleine Anzahl von Clients oder Knoten oder Maschinentypen ohne aktiviertes Tier 1-Netzwerk verwenden, wird der Benchmark von den Clients gedrosselt, bevor das Managed Lustre-Dateisystem sein Limit erreicht.
MPI-Kontextwechsel:Wenn
PROCESSES_PER_NODEhöher als die Anzahl der physischen Kerne auf Ihren Clientcomputern festgelegt ist, werden die CPU-Konkurrenz und der Overhead beim Kontextwechsel die E/A-Leistung des Benchmarks künstlich beeinträchtigen.Fehlende direkte E/A:Wenn das Flag
--posix.odirectweggelassen wird, werden Daten über den RAM-Seitencache des Clients übertragen. Dies führt zu Engpässen im Arbeitsspeicher und CPU-Overhead, die die tatsächliche Leistung des Netzwerkspeichers verdecken.
Bereinigen
Mit den folgenden Schritten vermeiden Sie, dass Ihrem Google Cloud Konto die auf dieser Seite verwendeten Ressourcen in Rechnung gestellt werden:
Löschen Sie die Testdateien aus dem Managed Lustre-Volume:
ssh -i ./id_rsa -o "StrictHostKeyChecking=no" -o UserKnownHostsFile=/dev/null ${SSH_USER}@${HEAD_NODE} "rm -rf /lustre/test"Löschen Sie die im Bulk erstellten Compute Engine-Clientcomputer:
gcloud compute instances delete $(gcloud compute instances list \ --filter="name~'^${CLIENT_PREFIX}-'" --format="value(name)" --zones="ZONE") \ --zone="ZONE"Alternativ können Sie die genauen Namen angeben oder sie einzeln löschen:
gcloud compute instances delete CLIENT_PREFIX-0001 CLIENT_PREFIX-0002 ... --zone=ZONEWenn Sie ein benutzerdefiniertes Image erstellt haben, können Sie es löschen:
gcloud compute images delete CUSTOM_IMAGE_NAMEWenn Sie die Managed Lustre-Instanz speziell für diesen Test erstellt haben und sie nicht mehr benötigen, löschen Sie sie:
gcloud lustre instances delete INSTANCE_ID --location=LOCATION
Häufige Engpässe beim Benchmarking beheben
Wenn Ihre Benchmark-Ergebnisse deutlich niedriger als die erwartete Speicherleistungsstufe sind, lesen Sie den Artikel Häufige Engpässe beheben.