none, mq-deadline, bfq und kyber im Praxisvergleich
Der Disk-I/O-Scheduler unter Linux entscheidet, in welcher Reihenfolge Lese- und Schreibanfragen an das Blockgeraet weitergereicht werden, lange bevor MySQL selbst etwas davon merkt. Auf NVMe-Storage kann die falsche Wahl mehr Latenz kosten als jede MySQL-Konfigurationsaenderung einsparen kann.
Inhaltsverzeichnis
- 1. Warum der I/O-Scheduler fuer Datenbanken relevant ist
- 2. Multi-Queue-Block-Layer und die verfuegbaren Scheduler
- 3. none: der Scheduler ohne Umsortierung
- 4. mq-deadline: Fairness mit Latenzgrenzen
- 5. bfq und kyber: wann sie doch sinnvoll sind
- 6. Den aktuellen Scheduler ermitteln und aendern
- 7. Persistente Konfiguration mit udev-Regeln
- 8. Mit fio den Unterschied messbar machen
- 9. Scheduler im direkten Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Warum der I/O-Scheduler fuer Datenbanken relevant ist
Jede Schreib- und Leseoperation, die MySQL an die Festplatte oder SSD schickt, durchlaeuft vor dem eigentlichen Storage-Geraet den Linux-Block-Layer, und dort entscheidet der Disk-I/O-Scheduler, in welcher Reihenfolge und mit welcher Prioritaet diese Anfragen tatsaechlich ausgefuehrt werden. Auf rotierenden Festplatten war diese Umsortierung historisch enorm wichtig, um teure Kopfbewegungen zu minimieren. Auf modernem NVMe- und SSD-Storage kehrt sich diese Logik teilweise um, weil das zugrunde liegende Medium keine mechanischen Kopfbewegungen mehr kennt.
Fuer einen MySQL-Server, der Innodb-Redo-Logs, Binlogs und Datendateien parallel schreibt, kann ein ungeeigneter Disk-I/O-Scheduler zusaetzliche Latenz einfuehren, die auf den ersten Blick wie ein Datenbankproblem aussieht, tatsaechlich aber im Block-Layer entsteht. Besonders bei Transaktions-Commits, die auf fsync() warten, summiert sich unnoetige Scheduler-Latenz direkt zur wahrgenommenen Antwortzeit von Magento-Checkouts.
Dieser Artikel zeigt, welche Scheduler der moderne Linux-Kernel anbietet, welcher fuer NVMe-basierte Datenbankserver die richtige Wahl ist, und wie man die Entscheidung mit echten Benchmarks statt mit Bauchgefuehl trifft.
2. Multi-Queue-Block-Layer und die verfuegbaren Scheduler
Seit Linux-Kernel 4.x hat der sogenannte Multi-Queue-Block-Layer (blk-mq) die aelteren Single-Queue-Scheduler wie cfq und deadline abgeloest. Der Multi-Queue-Ansatz verteilt I/O-Anfragen auf mehrere Hardware-Queues parallel, was auf modernen NVMe-Geraeten mit vielen parallelen Queues die eigentliche Staerke des Mediums ausnutzt. Fuer diesen neuen Layer stehen unter aktuellen Distributionen typischerweise vier Optionen zur Verfuegung: none, mq-deadline, bfq und kyber.
Welcher Disk-I/O-Scheduler aktuell fuer ein Blockgeraet aktiv ist, zeigt die virtuelle Datei unter /sys/block/[geraet]/queue/scheduler, wobei der aktive Scheduler in eckigen Klammern markiert ist. Diese Datei laesst sich auch zur Laufzeit beschreiben, um den Scheduler ohne Neustart zu wechseln, allerdings nur temporaer bis zum naechsten Boot, sofern keine persistente Regel konfiguriert wird.
# Show the currently active scheduler for an NVMe device
cat /sys/block/nvme0n1/queue/scheduler
# none [mq-deadline] bfq kyber
# Switch the scheduler at runtime (temporary until reboot)
echo none > /sys/block/nvme0n1/queue/scheduler
# List all block devices with their current scheduler
for dev in /sys/block/*/queue/scheduler; do
echo "$dev: $(cat "$dev")"
done
3. none: der Scheduler ohne Umsortierung
Der Scheduler none reicht I/O-Anfragen ohne jede Umsortierung direkt an das Blockgeraet weiter, mit minimalem CPU-Overhead im Kernel. Fuer NVMe-SSDs, die intern selbst hochparallele Command-Queues und einen eigenen Controller mit Wear-Leveling-Logik besitzen, ist diese Entscheidung meist die richtige: Das Geraet kann die eingehenden Anfragen selbst effizienter organisieren, als es ein zusaetzlicher Software-Scheduler im Kernel koennte.
Fuer einen dedizierten MySQL-Server auf NVMe-Storage, der keine anderen konkurrierenden I/O-intensiven Dienste auf demselben Geraet betreibt, liefert none in der Praxis regelmaessig die niedrigste Latenz bei zufaelligen Lese- und Schreibzugriffen, genau das Zugriffsmuster, das InnoDB fuer Redo-Logs und Buffer-Pool-Flushes erzeugt. Der Verzicht auf Umsortierung bedeutet dabei nicht Verzicht auf Fairness, weil moderne NVMe-Controller selbst ueber ausreichend interne Parallelitaet verfuegen, um mehrere gleichzeitige Anfragen effizient zu bedienen.
#!/usr/bin/env bash
# set-scheduler-none.sh — apply 'none' scheduler to a dedicated NVMe database disk
set -euo pipefail
DEVICE="nvme0n1"
SCHED_PATH="/sys/block/${DEVICE}/queue/scheduler"
if [[ ! -w "$SCHED_PATH" ]]; then
echo "[ERROR] $SCHED_PATH not writable, check device name" >&2
exit 1
fi
echo none > "$SCHED_PATH"
echo "[OK] Active scheduler for $DEVICE: $(cat "$SCHED_PATH")"
4. mq-deadline: Fairness mit Latenzgrenzen
Der Scheduler mq-deadline garantiert jeder Anfrage eine maximale Wartezeit, bevor sie zwingend ausgefuehrt wird, unabhaengig davon, wie viele neuere Anfragen zwischenzeitlich eingetroffen sind. Das verhindert, dass einzelne Requests unter staendig neu eintreffenden Anfragen verhungern, ein Szenario, das bei stark parallelem Zugriff durchaus vorkommt. Fuer SATA-SSDs und aeltere rotierende Festplatten, die keine so hochparallele interne Queue-Verwaltung wie NVMe-Geraete besitzen, bleibt mq-deadline die solidere Wahl.
Auch auf gemeinsam genutztem Storage, etwa wenn MySQL und andere Dienste dasselbe Blockgeraet teilen, sorgt mq-deadline fuer ausgewogenere Latenzverteilung zwischen konkurrierenden Workloads als none. Der Disk-I/O-Scheduler mq-deadline ist deshalb der aktuelle Standarddefault vieler Distributionen fuer nicht ausschliesslich NVMe-basierte Systeme, weil er ein robustes Verhalten ueber unterschiedlichste Storage-Typen hinweg liefert, ohne das Feintuning zu erfordern, das none auf gemischtem Storage manchmal braucht.
5. bfq und kyber: wann sie doch sinnvoll sind
Der Scheduler bfq (Budget Fair Queueing) verteilt die verfuegbare I/O-Bandbreite fair zwischen Prozessen, mit einstellbaren Prioritaeten pro Prozess oder Cgroup. Fuer einen dedizierten Datenbankserver, auf dem praktisch nur MySQL relevante I/O erzeugt, ist diese Fairness zwischen Prozessen meist unnoetig und kostet zusaetzlichen CPU-Overhead ohne messbaren Vorteil. Auf einem gemischten Server, der neben MySQL auch Backup-Jobs, Log-Rotation und andere I/O-intensive Hintergrundprozesse ausfuehrt, kann bfq jedoch verhindern, dass ein einzelner Backup-Lauf die Latenz der Datenbank-Queries in die Hoehe treibt.
Der Scheduler kyber zielt speziell auf Latenz-sensitive Workloads mit gemischten Lese- und Schreibmustern ab und versucht, konfigurierbare Ziel-Latenzen fuer Lese- und Schreibzugriffe getrennt einzuhalten. In der Praxis zeigt kyber auf reinen Datenbank-Workloads selten einen klaren Vorteil gegenueber none, kann aber auf gemischten Workloads mit vielen kleinen synchronen Lesezugriffen neben grossen sequentiellen Schreibvorgaengen eine interessante Alternative sein, die einen eigenen Benchmark wert ist.
# Configure bfq weight per cgroup for a shared server running MySQL + backups
# /sys/fs/cgroup/io.bfq.weight (cgroup v2, requires bfq scheduler active)
echo "default 500" > /sys/fs/cgroup/mysql.slice/io.bfq.weight
echo "default 100" > /sys/fs/cgroup/backup.slice/io.bfq.weight
# MySQL now receives roughly 5x the I/O bandwidth priority over backup jobs
6. Den aktuellen Scheduler ermitteln und aendern
Bevor ein Disk-I/O-Scheduler gewechselt wird, lohnt sich ein Blick darauf, ob das jeweilige Blockgeraet ueberhaupt eine echte rotierende Festplatte oder ein Solid-State-Geraet ist. Die Datei /sys/block/[geraet]/queue/rotational zeigt mit dem Wert 0 ein SSD- oder NVMe-Geraet an, mit 1 eine klassische Festplatte. Diese Information hilft, die richtige Scheduler-Empfehlung ueberhaupt erst korrekt zuzuordnen, denn ein Scheduler, der fuer rotierende Platten sinnvoll ist, kann auf einer NVMe-SSD kontraproduktiv sein.
Der Wechsel selbst erfolgt durch einfaches Schreiben des Scheduler-Namens in die scheduler-Datei, ohne dass ein Neustart des Systems oder des MySQL-Dienstes erforderlich ist. Diese Aenderung greift sofort fuer alle neuen I/O-Anfragen an das Geraet, laufende Anfragen werden nicht unterbrochen. Fuer produktive Systeme empfiehlt sich dennoch, den Wechsel ausserhalb von Spitzenlastzeiten durchzufuehren und die Auswirkung ueber iostat zu beobachten.
7. Persistente Konfiguration mit udev-Regeln
Eine Aenderung ueber echo in /sys/block/.../scheduler geht bei jedem Neustart verloren, weil der Kernel den Scheduler beim Booten wieder auf den Kernel- oder Distributions-Default zuruecksetzt. Fuer eine dauerhafte Konfiguration ist eine udev-Regel der zuverlaessigste Weg, den Disk-I/O-Scheduler automatisch bei jedem Boot und bei jedem Hinzufuegen des Geraets korrekt zu setzen, unabhaengig vom genauen Geraetenamen, der sich zwischen Neustarts theoretisch aendern kann.
Die Regel greift ueber den ID_MODEL oder die Kernel-Subsystem-Zuordnung und setzt den gewuenschten Scheduler-Wert, sobald das Geraet vom Kernel erkannt wird. Dieser Ansatz ist robuster als ein einfacher Systemd-Boot-Hook, weil udev auch bei Hot-Plug-Ereignissen greift, etwa wenn eine NVMe-Karte im laufenden Betrieb neu erkannt wird.
# /etc/udev/rules.d/60-io-scheduler.rules
# Persist 'none' scheduler for all NVMe devices across reboots
ACTION=="add|change", KERNEL=="nvme[0-9]n[0-9]", ATTR{queue/scheduler}="none"
# Persist 'mq-deadline' for rotational (spinning disk) devices
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="mq-deadline"
# Reload rules without reboot:
# udevadm control --reload-rules
# udevadm trigger --type=devices --action=change
8. Mit fio den Unterschied messbar machen
Behauptungen ueber die Vorteile eines Disk-I/O-Schedulers ohne eigene Messung sind wenig belastbar, weil die tatsaechliche Auswirkung stark von der konkreten Hardware, dem RAID-Layout und dem I/O-Muster der Anwendung abhaengt. Das Tool fio erlaubt es, den fuer InnoDB typischen Zugriffsmuster nachzubilden: viele kleine, zufaellige 16-Kilobyte-Schreibvorgaenge fuer Redo-Logs, gemischt mit groesseren sequentiellen Lesevorgaengen fuer Tabellen-Scans.
Ein Benchmark mit identischem fio-Profil, einmal pro zu testendem Scheduler ausgefuehrt, liefert vergleichbare Latenz- und Durchsatzwerte, auf deren Basis eine begruendete Entscheidung moeglich ist, statt sich auf generische Empfehlungen aus dem Internet zu verlassen, die moeglicherweise auf anderer Hardware gemessen wurden.
#!/usr/bin/env bash
# benchmark-io-scheduler.sh — compare schedulers with a MySQL-like access pattern
set -euo pipefail
DEVICE="/dev/nvme0n1"
SCHED_PATH="/sys/block/nvme0n1/queue/scheduler"
for scheduler in none mq-deadline bfq kyber; do
echo "$scheduler" > "$SCHED_PATH" 2>/dev/null || continue
echo "=== Testing scheduler: $scheduler ==="
fio --name=innodb-redo-sim \
--filename="$DEVICE" \
--rw=randwrite \
--bs=16k \
--iodepth=32 \
--direct=1 \
--runtime=30 \
--time_based \
--group_reporting \
--output-format=terse | tee -a "/tmp/fio-${scheduler}.log"
done
9. Scheduler im direkten Vergleich
Die folgende Tabelle fasst zusammen, welcher Disk-I/O-Scheduler fuer welches Storage- und Workload-Profil bei Datenbankservern die bessere Wahl ist.
| Scheduler | Passendes Storage | CPU-Overhead | Empfehlung fuer MySQL |
|---|---|---|---|
| none | Dedizierte NVMe-SSD | Minimal | Erste Wahl fuer Single-Purpose-DB-Server |
| mq-deadline | SATA-SSD, HDD, gemischtes Storage | Niedrig | Solider Default ohne Feintuning |
| bfq | Geteiltes Storage mit Fremd-Workloads | Hoch | Bei parallelen Backup-Jobs auf demselben Geraet |
| kyber | Latenz-sensitive Mischworkloads | Mittel | Nur nach eigenem fio-Benchmark einsetzen |
Fuer die klare Mehrheit der Magento-Datenbankserver auf dedizierter NVMe-Hardware liefert none die niedrigste Latenz bei minimalem CPU-Overhead. Der Disk-I/O-Scheduler mq-deadline bleibt die robuste Alternative fuer gemischtes oder aelteres Storage, waehrend bfq und kyber nur bei speziellen Anforderungen und nach eigenem Benchmark den Wechsel rechtfertigen.
Mironsoft
Linux-Storage-Tuning und Datenbank-Performance fuer Magento
Blockiert der falsche I/O-Scheduler Ihre Datenbank-Performance?
Wir analysieren Ihr Storage-Setup, benchmarken die verfuegbaren Scheduler mit realistischen MySQL-Zugriffsmustern und richten eine persistente, produktionsreife Konfiguration ein.
Storage-Analyse
NVMe-, SSD- und HDD-Setups auf den passenden Scheduler pruefen
fio-Benchmarking
Realistische InnoDB-Zugriffsmuster gegen verschiedene Scheduler messen
Persistente Konfiguration
udev-Regeln fuer dauerhaft korrekten Scheduler nach jedem Reboot
10. Zusammenfassung
Der richtige Disk-I/O-Scheduler haengt in erster Linie vom Storage-Typ ab: none ist fuer dedizierte NVMe-Datenbankserver die niedrigste Latenz mit dem geringsten Overhead, weil moderne NVMe-Controller die interne Organisation der Anfragen selbst effizient uebernehmen. mq-deadline bleibt der robuste Standard fuer SATA-SSDs, rotierende Festplatten und gemischtes Storage, weil er Fairness ohne aufwendiges Tuning liefert.
Spezialisierte Scheduler wie bfq und kyber lohnen sich nur in konkreten Szenarien mit konkurrierenden Workloads auf demselben Geraet oder besonders latenzsensiblen Mischmustern, und die Entscheidung sollte immer auf einem eigenen fio-Benchmark basieren statt auf generischen Empfehlungen. Persistente udev-Regeln stellen sicher, dass die getroffene Wahl auch nach einem Neustart bestehen bleibt.
Disk-I/O-Scheduler fuer Datenbankserver — Das Wichtigste auf einen Blick
NVMe-Server
none nutzen, der Controller organisiert Anfragen selbst effizienter als der Kernel-Scheduler.
Gemischtes Storage
mq-deadline als robuster Default fuer SATA-SSDs und rotierende Festplatten.
Messen statt raten
fio mit InnoDB-typischem Zugriffsmuster fuer jeden Scheduler einzeln benchmarken.
Persistenz
udev-Regeln fuer eine dauerhafte, reboot-feste Scheduler-Konfiguration einsetzen.