NUMA-Ueberlegungen bei Multi-CPU-Servern fuer Magento und MySQL
AI generated
$
/etc
Linux · NUMA · Multi-CPU · MySQL
NUMA-Ueberlegungen bei Multi-CPU-Servern
Warum entfernter Speicherzugriff Magento-Datenbanken ausbremst

Auf Multi-Socket-Servern ist nicht jeder Arbeitsspeicher fuer jede CPU gleich schnell erreichbar. NUMA beschreibt genau diese Asymmetrie, und wer MySQL oder PHP-FPM ohne Ruecksicht auf NUMA-Nodes betreibt, riskiert stille Latenzverluste, die kein einzelner Konfigurationswert im Anwendungslayer erklaeren kann.

17 Min. Lesezeit numactl · numastat · innodb_numa_interleave Linux · MySQL 8 · Multi-Socket-Hardware

1. Warum NUMA bei Multi-CPU-Servern relevant ist

Sobald ein Server mehr als eine physische CPU verbaut hat, aendert sich die Physik des Arbeitsspeicherzugriffs grundlegend. Jede CPU-Sockel bringt ihren eigenen Arbeitsspeicher-Controller mit und ist direkt an einen Teil des Gesamtspeichers angebunden. Greift ein Prozess auf Speicher zu, der an seinem eigenen Socket haengt, ist der Zugriff schnell. Muss die CPU stattdessen ueber den Interconnect zum Speicher des anderen Sockels greifen, entsteht spuerbar hoehere Latenz. Genau dieses Verhalten beschreibt NUMA, kurz fuer Non-Uniform Memory Access.

Fuer einen Magento-Server mit einer einzigen CPU spielt NUMA keine Rolle, weil es nur einen Speicherbereich gibt. Sobald aber ein Datenbankserver mit zwei oder mehr Sockeln betrieben wird, etwa fuer einen grossen InnoDB Buffer Pool oder mehrere PHP-FPM-Pools mit hoher Parallelitaet, entscheidet die NUMA-Platzierung von Prozessen und Speicher direkt darueber, ob die zusaetzliche Hardware tatsaechlich genutzt wird oder ob ein erheblicher Teil der Zugriffe ueber den langsameren entfernten Pfad laeuft.

Dieser Artikel zeigt, wie die NUMA-Topologie eines Servers ermittelt wird, wie MySQL und PHP-FPM auf ungeeignete NUMA-Platzierung reagieren, und mit welchen konkreten Werkzeugen Prozesse und Speicher gezielt auf denselben Node gebunden werden koennen.

2. NUMA-Architektur verstehen: Nodes und Speicherzugriff

Ein NUMA-Node besteht aus einer Gruppe von CPU-Kernen und dem Arbeitsspeicher, der physisch direkt an deren Speicher-Controller angeschlossen ist. Ein typischer Zwei-Sockel-Server bildet zwei NUMA-Nodes, ein Vier-Sockel-Server entsprechend vier. Innerhalb eines Nodes ist der Speicherzugriff lokal und schnell. Greift ein Prozess auf einem Kern von Node 0 auf Speicher zu, der physisch an Node 1 haengt, muss die Anfrage ueber eine Interconnect-Verbindung laufen, etwa Intel UPI oder AMD Infinity Fabric, was zusaetzliche Zyklen kostet.

Der Linux-Kernel ist sich dieser Topologie bewusst und versucht standardmaessig, Prozesse und den von ihnen angeforderten Speicher auf demselben NUMA-Node zu platzieren, ein Verhalten, das als First-Touch-Policy bekannt ist: Der Speicher wird auf dem Node alloziert, auf dem der anfragende Thread gerade laeuft. Problematisch wird es, wenn ein Prozess zwischen Nodes migriert wird, etwa durch den Scheduler, oder wenn ein Prozess von Anfang an mehr Speicher braucht, als ein einzelner Node bereitstellen kann. In beiden Faellen entstehen dauerhaft entfernte Speicherzugriffe, die sich in Benchmarks als erhoehte Latenz ohne erkennbare CPU-Ausl astung zeigen.

Fuer Datenbank-Workloads mit grossem Buffer Pool ist genau dieser zweite Fall der Normalfall: Ein Buffer Pool von 64 Gigabyte passt selten vollstaendig in den Speicher eines einzelnen NUMA-Nodes, wenn der Server insgesamt 128 Gigabyte auf zwei Nodes verteilt hat. Ohne gezielte Konfiguration verteilt sich der Buffer Pool dann unguenstig, mit spuerbaren Folgen fuer die Latenz einzelner Queries.

3. Die eigene NUMA-Topologie mit numactl ermitteln

Bevor irgendeine NUMA-Optimierung sinnvoll ist, muss die tatsaechliche Topologie des Servers bekannt sein. Das Paket numactl liefert dafuer die notwendigen Werkzeuge. Der Befehl numactl --hardware zeigt, wie viele NUMA-Nodes existieren, wie viel Speicher jedem Node zugeordnet ist, und wie teuer der Zugriff zwischen den Nodes relativ zueinander ist, ausgedrueckt in der sogenannten Distance-Matrix.

Ergaenzend liefert lscpu eine Uebersicht, welche CPU-Kerne zu welchem NUMA-Node gehoeren. Diese Zuordnung ist notwendig, um spaeter Prozesse gezielt an die richtigen Kerne binden zu koennen. Auf virtualisierten Servern ist zu beachten, dass die vom Hypervisor gemeldete NUMA-Topologie nicht immer der physischen Hardware entspricht, ein vServer kann eine einzelne Node melden, obwohl der Host mehrere Sockel besitzt.


# Show NUMA nodes, memory per node, and inter-node distance
numactl --hardware
# available: 2 nodes (0-1)
# node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11
# node 0 size: 64729 MB
# node 1 cpus: 12 13 14 15 16 17 18 19 20 21 22 23
# node 1 size: 64768 MB
# node distances:
# node   0   1
#   0:  10  21
#   1:  21  10

# Show which CPU cores belong to which NUMA node
lscpu | grep -i numa
# NUMA node(s):        2
# NUMA node0 CPU(s):   0-11
# NUMA node1 CPU(s):   12-23

# Confirm actual current memory usage per node
cat /sys/devices/system/node/node*/meminfo | grep MemFree

4. Wie NUMA MySQL und PHP-FPM konkret beeinflusst

Bei MySQL zeigt sich der NUMA-Effekt am deutlichsten beim InnoDB Buffer Pool. Startet MySQL ohne NUMA-Beruecksichtigung auf einem Zwei-Node-System, alloziert der Kernel den Buffer Pool nach der First-Touch-Policy meist auf einem einzigen Node, weil der Hauptthread beim Start dort laeuft. Nachfolgende Query-Threads, die auf Kernen des anderen Nodes eingeplant werden, greifen dann staendig entfernt auf den Buffer Pool zu, was die effektive Speicherlatenz fuer diese Threads erhoeht, obwohl der Server insgesamt genug freien Speicher hat.

Bei PHP-FPM ist der Effekt subtiler, aber ebenfalls messbar: Viele parallele PHP-FPM-Worker-Prozesse, die vom Scheduler ueber beide NUMA-Nodes verteilt werden, konkurrieren teilweise um denselben Interconnect-Bandbreitenpfad, wenn sie gleichzeitig auf gemeinsam genutzten Speicher zugreifen, etwa OPcache-Shared-Memory-Segmente. Auf Servern mit sehr hoher PHP-FPM-Parallelitaet und knapper CPU-Zuteilung pro Request kann diese Interconnect-Last einen Teil der theoretisch verfuegbaren Rechenleistung effektiv unerreichbar machen.

In beiden Faellen ist das Symptom aehnlich: Die CPU-Auslastung sieht unauffaellig aus, aber die Antwortzeiten schwanken staerker als erwartet, und ein Blick auf klassische Metriken wie Load Average oder CPU-Prozent liefert keine Erklaerung. Erst eine NUMA-spezifische Analyse zeigt, wie viele Speicherzugriffe tatsaechlich entfernt erfolgen.

5. numactl: Prozesse gezielt an NUMA-Nodes binden

Die direkteste Massnahme ist, einen Prozess von vornherein an einen bestimmten NUMA-Node zu binden, sowohl fuer die CPU-Zuteilung als auch fuer die Speicherallokation. Der Befehl numactl --cpunodebind=0 --membind=0 startet einen Prozess so, dass er ausschliesslich auf den CPU-Kernen von Node 0 laeuft und seinen Speicher ausschliesslich von Node 0 anfordert. Das eliminiert entfernte Zugriffe vollstaendig, solange der Prozess nicht mehr Speicher braucht, als der Node bereitstellt.

Fuer MySQL bedeutet das in der Praxis: Wenn der Buffer Pool kleiner ist als der Speicher eines einzelnen NUMA-Nodes, ist striktes Node-Binding meist die beste Wahl, weil die gesamte Datenbank dann konsequent lokal arbeitet, allerdings auf Kosten der Rechenleistung des zweiten Sockels, der fuer MySQL ungenutzt bleibt.


# /etc/systemd/system/mysql.service.d/numa.conf
# Bind MySQL to NUMA node 0 for both CPU and memory
[Service]
ExecStart=
ExecStart=/usr/bin/numactl --cpunodebind=0 --membind=0 /usr/sbin/mysqld

systemctl daemon-reload
systemctl restart mysql

# Verify the running process is actually bound to node 0
numastat -p $(pgrep mysqld)

6. NUMA-Interleaving fuer den InnoDB Buffer Pool

Passt der Buffer Pool nicht mehr in einen einzelnen NUMA-Node, ist striktes Binding keine Option mehr. Fuer diesen Fall bietet MySQL seit Version 5.7 die Option innodb_numa_interleave, die den Buffer Pool bewusst gleichmaessig ueber alle verfuegbaren NUMA-Nodes verteilt, statt ihn auf einem einzigen Node zu konzentrieren. Interleaving sorgt dafuer, dass jeder Thread im Durchschnitt die gleiche Mischung aus lokalen und entfernten Zugriffen erfaehrt, statt dass ein Teil der Threads durchgaengig entfernt zugreift, waehrend der andere Teil durchgaengig lokal arbeitet.

Diese gleichmaessige Verteilung ist kein Ersatz fuer lokalen Speicherzugriff, verhindert aber das schlimmste Szenario: einen Buffer Pool, der komplett auf dem falschen Node liegt, waehrend die meisten Anfragen auf dem anderen Node ankommen. Fuer Buffer Pools, die deutlich groesser sind als ein einzelner Node, ist Interleaving in der Praxis meist die bessere Wahl gegenueber striktem Binding.


# /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
# Spread the buffer pool evenly across all NUMA nodes
# instead of concentrating it on a single node
innodb_numa_interleave = 1
innodb_buffer_pool_size = 96G
innodb_buffer_pool_instances = 12

7. Kernel-Parameter und BIOS-Einstellungen fuer NUMA

Der Kernel-Parameter numa_balancing aktiviert Automatic NUMA Balancing, eine Funktion, die versucht, laufende Prozesse und ihre Speicherseiten nachtraeglich naeher zusammenzubringen, indem Seiten periodisch zwischen Nodes verschoben werden. Fuer viele Workloads ist das hilfreich, fuer einen dauerhaft laufenden Datenbankprozess mit riesigem Buffer Pool verursacht das periodische Verschieben grosser Speicherbereiche aber selbst spuerbare Latenzspitzen, aehnlich wie bei Transparent Huge Pages. Auf dedizierten Datenbankservern mit expliziter NUMA-Konfiguration wird Automatic Balancing deshalb ueblicherweise deaktiviert.

Auf Hardware-Ebene bieten viele Server-Mainboards eine BIOS-Option namens Node Interleaving oder aehnlich, die die NUMA-Topologie komplett vor dem Betriebssystem verbirgt und den Speicher als eine einzige, uniforme Zone praesentiert. Das klingt komfortabel, entfernt aber jede Moeglichkeit zur gezielten Optimierung und sollte auf Datenbankservern deaktiviert bleiben, damit Linux und MySQL die tatsaechliche Topologie sehen und darauf reagieren koennen.


# Check current Automatic NUMA Balancing state
cat /proc/sys/kernel/numa_balancing
# 1 = enabled

# Disable for dedicated database servers with explicit NUMA config
echo 0 > /proc/sys/kernel/numa_balancing

# Persist across reboots
echo 'kernel.numa_balancing = 0' > /etc/sysctl.d/61-numa.conf
sysctl -p /etc/sysctl.d/61-numa.conf

8. NUMA-bedingte Performance-Probleme diagnostizieren

Das Werkzeug numastat zeigt pro Prozess, wie viele Speicherzugriffe lokal (numa_hit) und wie viele ueber einen anderen Node hinweg (numa_foreign, other_node) erfolgt sind. Ein hoher Anteil an other_node-Zugriffen im Verhaeltnis zu numa_hit ist ein klares Indiz dafuer, dass ein Prozess ungeguenstig platziert ist. Fuer MySQL laesst sich dieser Wert direkt mit der Prozess-ID des mysqld-Prozesses abfragen.

Ergaenzend zeigt numastat -m die Speicherverteilung ueber alle Nodes systemweit, was hilft zu erkennen, ob ein Node ueberproportional stark belegt ist, waehrend ein anderer Node grosse Mengen freien Speichers hat, der von der Anwendung nicht erreicht wird. In Kombination mit perf stat -e und den passenden Hardware-Zaehlern fuer entfernte Speicherzugriffe laesst sich das Problem quantitativ auf einzelne Zeitraeume eingrenzen, statt nur auf einen Verdacht angewiesen zu sein.


# Per-process NUMA hit/miss statistics for the mysqld process
numastat -p $(pgrep mysqld)
# Per-node memory statistics                           Node 0          Node 1
# numa_hit                                          48213221        41029013
# numa_miss                                                0               0
# numa_foreign                                            0               0
# other_node                                         9021113        11238042

# System-wide memory distribution across NUMA nodes
numastat -m | head -5

9. NUMA-Strategien im Vergleich

Welche NUMA-Strategie fuer einen Server sinnvoll ist, haengt vor allem davon ab, wie gross der Buffer Pool im Verhaeltnis zum Speicher eines einzelnen Nodes ist. Die folgende Tabelle stellt die drei praxisrelevanten Optionen gegenueber.

Strategie Wann sinnvoll Nachteil
Striktes Binding (numactl) Buffer Pool passt in einen einzelnen Node Zweiter Sockel bleibt fuer MySQL ungenutzt
Interleaving (innodb_numa_interleave) Buffer Pool groesser als ein einzelner Node Gleichmaessig gemischte Latenz statt rein lokal
Automatic NUMA Balancing (Default) Wechselnde, unvorhersehbare Workloads Periodisches Seiten-Verschieben verursacht Latenzspitzen
Node Interleaving im BIOS Praktisch nie fuer Datenbankserver Verbirgt Topologie, keine Optimierung mehr moeglich

Fuer die grosse Mehrheit produktiver Magento-Datenbankserver mit einem Buffer Pool, der einen guten Teil des Gesamtspeichers ausmacht, ist Interleaving mit deaktiviertem Automatic Balancing die robusteste Wahl. Striktes Binding lohnt sich nur, wenn der Buffer Pool bewusst klein genug gehalten wird, um in einen Node zu passen, und der Server ohnehin mehrere unabhaengige Dienste auf getrennten Sockeln betreibt.

Mironsoft

Multi-Socket-Server-Tuning fuer Magento-Datenbanken

Nutzt Ihr Multi-CPU-Server die zweite Sockel-Haelfte wirklich?

Wir analysieren Ihre NUMA-Topologie, messen entfernte Speicherzugriffe mit numastat und konfigurieren MySQL sowie PHP-FPM fuer stabile, latenzarme Performance auf Multi-Socket-Hardware.

NUMA-Analyse

Topologie und Speicherverteilung mit numactl und numastat vermessen

MySQL-Tuning

Interleaving oder striktes Node-Binding passend zur Buffer-Pool-Groesse

Monitoring

Entfernte Zugriffe dauerhaft ueberwachen und Regressionen erkennen

10. Zusammenfassung

NUMA beschreibt die Asymmetrie zwischen lokalem und entferntem Speicherzugriff auf Multi-Socket-Servern und wird auf Einzel-Sockel-Systemen komplett irrelevant. Sobald ein Server ueber mehrere NUMA-Nodes verfuegt, entscheidet die Platzierung von MySQL und PHP-FPM darueber, wie viele Speicherzugriffe teuer ueber den Interconnect laufen. Mit numactl --hardware und lscpu laesst sich die Topologie ermitteln, mit numastat die tatsaechliche Verteilung der Zugriffe messen.

Fuer kleine Buffer Pools ist striktes Node-Binding mit numactl --cpunodebind --membind die einfachste und effektivste Loesung. Fuer grosse Buffer Pools, die ueber mehrere Nodes verteilt werden muessen, liefert innodb_numa_interleave eine gleichmaessige und vorhersehbare Verteilung. Automatic NUMA Balancing sollte auf dedizierten Datenbankservern mit expliziter Konfiguration deaktiviert werden, weil es selbst Latenzspitzen verursachen kann.

NUMA-Ueberlegungen bei Multi-CPU-Servern — Das Wichtigste auf einen Blick

Topologie ermitteln

numactl --hardware und lscpu zeigen Nodes, Speichergroesse und Distance-Matrix.

Kleiner Buffer Pool

Striktes Binding mit numactl --cpunodebind --membind auf einen Node.

Grosser Buffer Pool

innodb_numa_interleave = 1 fuer gleichmaessige Verteilung ueber alle Nodes.

Diagnose

numastat -p zeigt lokale vs. entfernte Zugriffe pro Prozess.

11. FAQ: NUMA-Ueberlegungen bei Multi-CPU-Servern

1Was bedeutet NUMA konkret?
Lokaler Speicherzugriff auf Multi-Socket-Servern ist schneller als der Zugriff auf Speicher eines anderen Sockels.
2Betrifft NUMA Single-Socket-Server?
Nein, bei einer CPU gibt es nur einen Node, die Asymmetrie existiert nicht.
3Wie finde ich die Anzahl NUMA-Nodes?
Mit numactl --hardware oder lscpu, beide zeigen Nodes, Speicher und Kernzuordnung.
4Immer MySQL an einen Node binden?
Nur wenn der Buffer Pool in einen Node passt, sonst ist Interleaving besser.
5Was macht innodb_numa_interleave?
Verteilt den Buffer Pool gleichmaessig ueber alle NUMA-Nodes statt auf einem Node zu konzentrieren.
6Automatic NUMA Balancing deaktivieren?
Auf dedizierten Datenbankservern mit expliziter Konfiguration ja, wegen eigener Latenzspitzen.
7Wie erkenne ich NUMA-Probleme?
numastat -p zeigt lokale vs. entfernte Zugriffe pro Prozess-ID.
8Node Interleaving im BIOS aktivieren?
Nein, das verbirgt die Topologie und verhindert jede gezielte Optimierung.
9Wirkt sich NUMA auf PHP-FPM aus?
Ja, viele parallele Worker koennen bei ungeeigneter Platzierung um Interconnect-Bandbreite konkurrieren.
10Aendert sich NUMA auf virtuellen Servern?
Ja, der Hypervisor kann eine andere Topologie melden als die physische Hardware.