2023-11-03
Aktualisierungen des H2O.ai db-benchmark!
Tom Ebergen
Der Benchmark wurde aktualisiert!
Im April hat DuckLabs einen Blogbeitrag mit aktualisierten H2O.ai-db-benchmark-Ergebnissen veröffentlicht. Seither wurden die Ergebnisse nicht mehr aktualisiert. Ursprünglich sollten die Ergebnisse mit jedem DuckDB-Release nachgezogen werden. Kürzlich erschien DuckDB 0.9.1, und DuckLabs hat den Benchmark aktualisiert. Beim Aktualisieren ist uns aufgefallen, dass unser ursprüngliches Setup nicht für alle Lösungen fair war. Die Maschine nutzte Netzwerkspeicher und konnte unter noisy neighbors leiden. Um das zu vermeiden, wurde der gesamte Benchmark auf einer c6id.metal-Maschine neu ausgeführt.
Neue Benchmark-Umgebung: Instanz c6id.metal
Beim ersten Versuch, die Ergebnisse zu aktualisieren, kamen merkwürdige Zahlen heraus. Selbst mit denselben Bibliotheksversionen wie beim vorherigen Update wurden manche Lösungen langsamer, andere schneller. Wir führen diese Schwankung auf den gewählten AWS-EC2-Instanztyp zurück: m4.10xlarge.
Die m4.10xlarge hat 40 virtuelle CPUs und EBS-Speicher. EBS ist hochverfügbarer Netzwerk-Blockspeicher für EC2-Instanzen. Bei rechenintensiven Benchmarks kann eine Maschine wie die m4.10xlarge unter folgenden Problemen leiden:
-
Netzwerkspeicher ist ein Problem für Lösungen, die häufig mit dem Speicher interagieren. Bei den Workloads mit 500 MB und 5 GB war Netzwerkspeicher auf der
m4.10xlargekein Thema, weil alle Lösungen die Abfragen im Speicher ausführen konnten. Beim 50-GB-Workload dagegen war Netzwerkspeicher ein Problem für Lösungen, die nicht im Speicher bleiben konnten. Diem4.10xlargehat zwar dedizierte EBS-Bandbreite, jeder Lese- und Schreibzugriff läuft aber trotzdem über das Netzwerk – in der Regel langsamer als lokal montierter Speicher. Lösungen, die bei den 50-GB-Abfragen häufig auf den Speicher zugreifen, tun das über das Netzwerk. Diese Netzwerkzeit wird Teil der Ausführungszeit. Schwankt die Netzwerkleistung, schwankt auch die Abfrageleistung. -
Noisy neighbors sind ein häufiges Problem beim Benchmarking auf virtuellen CPUs. Die vorherige Maschine hat sich die Rechenhardware höchstwahrscheinlich mit anderen (benachbarten) AWS-EC2-Instanzen geteilt. Laufen dort ebenfalls rechenintensive Workloads, werden die physischen CPU-Caches ständig von der Nachbarinstanz und der Benchmark-Instanz invalidiert bzw. geleert. Teilen sich zwei Workloads auf zwei Instanzen den CPU-Cache, müssen beide häufiger aus dem Speicher nachladen – Daten, die auf einer nicht-virtuellen Maschine schon im Cache wären.
Um allen Lösungen gerecht zu werden, haben wir den Instanztyp auf eine Metal-Instanz mit lokalem Speicher umgestellt. Metal-Instanzen vermeiden noisy-neighbor-Probleme, weil die Hardware physisch ist und nicht mit anderen AWS-Nutzern oder -Instanzen geteilt wird. Auch Netzwerkspeicher entfällt: Lösungen können auf den lokalen Instanzspeicher lesen und schreiben, der physisch an der Hardware hängt.
Ein weiterer Vorteil der c6id.metal ist die Belastung der Parallelleistung. Es gibt 128 Kerne. Unterschiede zwischen Lösungen, die jeden Kern effektiv nutzen, und solchen, die das nicht tun, werden deutlich sichtbar.
Im Abschnitt Aktualisierte Einstellungen steht, wie die Einstellungen der einzelnen Lösungen auf der neuen Maschine geändert wurden.
Aktualisierung des Benchmarks
Künftig aktualisieren wir den Benchmark, wenn PRs mit neuen Leistungszahlen eingehen. Der PR sollte eine Beschreibung der Änderungen am Lösungsskript oder an der Version enthalten sowie neue Einträge in den Dateien time.csv und logs.csv. Diese Einträge werden auf einer anderen c6id.metal-Instanz geprüft; bei geringer Abweichung wird der PR gemerged und die Ergebnisse aktualisiert.
Aktualisierte Einstellungen
- ClickHouse
- Speicher: Daten, die auf die Platte ausgelagert werden, müssen ebenfalls auf dem NVMe-Laufwerk liegen. Das wurde im neuen Skript
format_and_mount.shund in der Dateiclickhouse/clickhouse-mount-config.xmlgeändert.
- Speicher: Daten, die auf die Platte ausgelagert werden, müssen ebenfalls auf dem NVMe-Laufwerk liegen. Das wurde im neuen Skript
- Julia (juliadf & juliads)
- Threads: Die Threads waren für juliadf/juliads fest auf 20/40 gesetzt. Jetzt wird die maximale Thread-Anzahl genutzt. Eine Option zum Auslagern auf die Platte gab es nicht, das wurde daher nicht geändert bzw. nicht weiter untersucht.
- DuckDB
- Speicher: Die DuckDB-Datenbankdatei wurde auf den NVMe-Mount gelegt.
- Spark
- Speicher: Es gibt eine Option zum Auslagern auf die Platte. Wie der Speicherort auf das NVMe-Laufwerk umgestellt wird, war uns unklar. Ein PR mit geänderter Speicherlage und besseren Ergebnissen ist willkommen!
Viele Lösungen lagern nicht auf die Platte aus und brauchten daher keine Anpassung für den Instanzspeicher. Andere nutzen parallel::ncores() oder standardmäßig die maximale Kernanzahl. Die Lösungsskripte wurden in der aktuellen Form auf github.com/duckdblabs/db-benchmark ausgeführt. Im Abschnitt Updating the Benchmark steht, wie Sie Ihre Lösung erneut ausführen.
Ergebnisse
Die ersten Ergebnisse sind die 50-GB-Group-by-Ergebnisse. Der Benchmark führt jede Abfrage zweimal pro Lösung aus und berichtet beide Laufzeiten. Die „erste Zeit“ gilt als kalter Lauf, die „zweite Zeit“ als warmer. DuckDB und DuckDB-latest schneiden bei allen Datensatzgrößen und Varianten sehr gut ab.
Das Team bei DuckLabs hat intensiv an der Leistung der Out-of-Core-Hash-Aggregationen und Joins gearbeitet. Die auffälligste Verbesserung ist die Leistung von Query 5 bei den erweiterten Group-by-Abfragen. Der kalte Lauf ist fast eine Größenordnung besser als jede andere Lösung! DuckDB ist außerdem eine von nur zwei Lösungen, die die 50-GB-Join-Abfrage beenden. Manche Lösungen laufen bei den 50-GB-Datensätzen in Timeouts. Lösungen bei den 50-GB-Group-by-Abfragen werden nach 180 Minuten beendet; alle 10 Group-by-Abfragen müssen also in 180 Minuten fertig werden. Lösungen bei den 50-GB-Join-Abfragen werden nach 360 Minuten beendet.