- Die Verarbeitung von rund 1,75 GB Schachpartie-Daten mit Kommandozeilen-Tools statt mit Hadoop war in nur 12 Sekunden abgeschlossen und damit mehr als 235-mal schneller als Hadoop mit 26 Minuten
- Durch die Kombination grundlegender Shell-Befehle wie grep, sort, uniq, awk, xargs, mawk wurde eine Streaming-Verarbeitungspipeline aufgebaut, die den Speicherverbrauch nahezu bei null hielt
- Durch Parallelisierung mit xargs und Optimierung mit mawk wurde die CPU-Kernauslastung erhöht und IO-Engpässe minimiert
- Im Vergleich zur Verarbeitung desselben Datensatzes auf einem Hadoop-Cluster (7
c1.medium-Instanzen) lagen Kosten und Wartungsaufwand deutlich niedriger - Der Beitrag zeigt, dass auch auf einer einzelnen Maschine effiziente Datenanalyse möglich ist, und mahnt zu mehr Vorsicht beim unnötigen Einsatz von Big-Data-Tools
Einleitung: Schnellere Kommandozeilen-Verarbeitung als Hadoop
- Nach einem Beispiel zur Analyse von rund 2 Millionen Schachpartien mit Amazon EMR und mrjob wurde dieselbe Datenanalyse mit Streaming-Verarbeitung auf Kommandozeilenbasis nachgebaut
- Auf einem Hadoop-Cluster (7
c1.medium) dauerte es 26 Minuten, Durchsatz 1,14 MB/sec - Auf einem lokalen Notebook war die Verarbeitung in 12 Sekunden abgeschlossen, Durchsatz 270 MB/sec
- Auf einem Hadoop-Cluster (7
- Es wird gezeigt, dass einfache Aggregationsaufgaben mit einer Shell-Pipeline wesentlich effizienter als mit Hadoop ausgeführt werden können
- Durch die Kombination von Shell-Befehlen lässt sich auf einer einzelnen Maschine eine parallele Stream-Verarbeitungsstruktur ähnlich Storm umsetzen
Datenstruktur und Vorbereitung
- Die Daten liegen im Format PGN (Portable Game Notation) vor; das Ergebnis jeder Partie steht in der Zeile
"Result""1-0"bedeutet Sieg für Weiß,"0-1"Sieg für Schwarz,"1/2-1/2"ein Unentschieden
- Aus dem GitHub-Repository rozim/ChessData wurde ein Datensatz von rund 3,46 GB bezogen
- Etwa doppelt so groß wie die Versuchsdaten von Tom Hayden (1,75 GB)
Aufbau der Basispipeline
- Zur Messung der IO-Grenze wurde
cat *.pgn > /dev/nullausgeführt; das dauerte rund 13 Sekunden (272 MB/sec) - Basispipeline für die Analyse:
cat *.pgn | grep "Result" | sort | uniq -c- Laufzeit rund 70 Sekunden, etwa 47-mal schneller als Hadoop
- AWK wurde anstelle von
sort | uniqverwendet, um die Ergebnisse direkt zu aggregieren- Laufzeit 65 Sekunden, nahezu kein Speicherverbrauch
grepbelegte einen einzelnen CPU-Kern und wurde zum Engpass
Parallelisierung und Optimierung
- xargs wurde zur Parallelisierung von
grepgenutztfind . -type f -name '*.pgn' -print0 | xargs -0 -n1 -P4 grep -F "Result" | gawk ...- Laufzeit 38 Sekunden, etwa 77-mal schneller
grepwurde entfernt und der Ablauf auf reines Filtern mit AWK vereinfacht- Zur Zusammenführung der Ergebnisse je Datei wurde eine doppelte AWK-Pipeline aufgebaut
- Laufzeit 18 Sekunden, etwa 174-mal schneller
- Durch den Wechsel zu mawk wurde weiter optimiert
find . -type f -name '*.pgn' -print0 | xargs -0 -n4 -P4 mawk ... | mawk ...- Laufzeit 12 Sekunden, 235-mal schneller als Hadoop, Durchsatz 270 MB/sec
Fazit: Die Effizienz der Einfachheit
- Außer in Fällen, in denen wirklich groß angelegte verteilte Verarbeitung nötig ist, ist die Kombination von Shell-Tools auf einer einzelnen Maschine schneller und wirtschaftlicher
- Hadoop wird oft übermäßig eingesetzt, obwohl für viele Aufgaben relationale Datenbanken oder einfache Skripte ausreichen
- Streaming-Analyse auf Kommandozeilenbasis ist eine starke Alternative in Bezug auf Leistung, Implementierungskosten und Wartbarkeit
2 Kommentare
Früher gab es einmal den Begriff der Taco-Bell-Programmierung, das wirkt wie eine ähnliche Philosophie.
Hacker-News-Kommentare
Das Traurigste daran ist, dass dieser Beitrag von 2014 ist
Inzwischen gibt es noch mehr Abstraktionsschichten wie Airflow, dbt, Snowflake, die selbst auf Datensätze gestapelt werden, die komplett in den RAM passen
Startups verbrennen 5.000 Dollar im Monat für verteilte Cluster, um weniger als 10 GB Logs pro Tag zu verarbeiten. Der Grund: Mit dem „Modern Data Stack“ wird man befördert, aber wenn man es mit einem bash-Skript löst, wird es als „nicht skalierbar“ abgetan. Effizienz und Anreize sind völlig entkoppelt
Es gab sogar einen Fall mit 1 GB JSON-Ingestion pro Tag, und als ich erklärte, dass eine Maschine ausreicht, hieß es: „Technisch stimmt das, aber das ist nicht die Antwort, die wir hören wollen“, und ich wurde abgelehnt
Heutige Maschinen haben RAM im TB-Bereich und Hunderte von Kernen. Eine einzelne Maschine ist bereits enorm groß
Wenn man bei DevOps-Einstellungen Erfahrung mit schicken Frameworks hervorhebt, kommen diese Leute ins Unternehmen und wiederholen dort genau das Gleiche
Niemand widerspricht, also wird am Ende eine Aufgabe verkompliziert, für die ein einzelner Desktop völlig ausreichen würde
Mit einem Lebenslauf, in dem kaum die neuesten Frameworks vorkommen, suche ich seit über einem Jahr nach einem Job und komme mir langsam wie ein Idiot vor
2014 waren 4 GB üblich, aber heute ist auch SSD-Streaming schnell genug, dass das Lesen von einer lokalen SSD manchmal besser ist als ein Cluster
Hier ist der Autor!
Es freut mich, dass der alte Beitrag immer noch hilfreich ist
Ich stimme zu, dass die Lage schlimmer geworden ist, aber gleichzeitig ist es beruhigend zu sehen, dass sich manche vom Microservices-Kult lösen
Allen, die an Performance-Verbesserungen arbeiten, drücke ich die Daumen. Es gibt noch Hoffnung
Ich habe den Beitrag mehrfach wieder gelesen und mich davon inspirieren lassen, die Waters-Series nach JavaScript zu portieren, um Stream-Pipelining umzusetzen
In der Branche ist die Vorstellung derzeit viel zu stark, dass Spark oder verteilte Tools die Standardantwort für Data Engineering seien
Das ähnelt dem übermäßigen Einsatz von SPA-Frameworks in der Webentwicklung
Mein Rat ist folgender:
Manager wollen nicht hören, dass „alles unbegrenzt skaliert“, sondern dass es „zuverlässig läuft“
Datengrößen folgen einem Potenzgesetz, daher gibt es nur sehr wenige Ingenieure, die mit Daten im Petabyte-Bereich arbeiten
Weil man solche Erfahrungen aber für höhere Gehälter im Lebenslauf haben will, entsteht Overengineering
Auf meine Frage nach dem Grund hieß es nur: „Wir müssen es einfach einsetzen.“ Vermutlich für den Lebenslauf oder aus politischen Gründen irgendeiner Person
Eine historische Anmerkung zum Beitrag
Ein Tool namens mrjob konnte auch ohne Hadoop im lokalen Modus laufen
Bei kleinen Datensätzen war es viel schneller als ein Cluster, insbesondere schneller als kurzlebige Cluster wie AWS EMR
Aber der Ansatz des Autors dürfte sogar noch effizienter gewesen sein
MapReduce machte großskalige Verteilung zwar einfach, brachte für kleine Datenmengen aber viele ineffiziente Einschränkungen mit sich
Anfang der 2010er wurden mit mrjob Datensätze im Petabyte-Bereich verarbeitet, heute wird es aber kaum noch verwendet
Als ich als Data Engineer gearbeitet habe, habe ich Bash-/Python-Skripte in C# neu geschrieben und die JSON-Verarbeitung auf 1 GB/s gebracht
Schon reine Optimierungen wie Streaming-Parsing machten einen großen Unterschied
Deshalb frage ich mich: Ab welcher Datenmenge ergibt Clustering eigentlich wirklich Sinn?
Für mich ist verteilte Verarbeitung dann einen Blick wert, wenn ein Job länger als einen Tag läuft
Bei großen Datenmengen habe er per Sampling gearbeitet und die Analyse in Excel gemacht. Heute lassen sich dank LLMs auch einfache Python-/Bash-Skripte leicht schreiben
Man kann direkt aus Object Storage wie S3 lesen und dorthin schreiben, und heute sind auch 100 GB/s möglich
Er passt auf Festplatten, aber nicht auf ein gewöhnliches Notebook
Wie „groß“ Daten sind, hängt davon ab, was man damit macht
Bei OP-Daten reichen für einfache Statistiken bash-Skripte, aber wenn man die Korrelation zwischen Arzt-Erfahrung und Erfolgsquote berechnen will, steigt die Komplexität sprunghaft
Daher ist es für Unternehmen viel einfacher zu sagen: „Wir verwenden Spark“, als zu sagen: „Wir bauen für jede Frage eine maßgeschneiderte Engine“
Alle genannten Probleme lassen sich auf einem einzelnen Server mit einfachen Tools lösen
Dieser Beitrag wurde früher schon mehrfach auf HN gepostet
Die Version von 2018, die Version von 2022 und die Version von 2024 wurden alle vom selben Einreicher gepostet
Das erinnert mich an den Einführungssatz auf der alten Shakti-Website
„1K Zeilen: Excel / 1M Zeilen: Pandas / 1B Zeilen: Shakti / 1T Zeilen: Only Shakti“
Quelle
Viele Entwickler lernen in einer Windows-Umgebung und sind deshalb mit CLI-Tools nicht vertraut
Dabei bietet die CLI mächtige Funktionen wie implizite Schleifen, automatische Feldtrennung und parallele Anwendung regulärer Ausdrücke
Dadurch kann man schnell Ad-hoc-Lösungen bauen und hat einen guten Ausgangspunkt, bevor man zu großen Systemen greift
Ich frage mich, wie ein neuer Benchmark aussähe, wenn man die Schachdaten deutlich größer skaliert
Der heutige Lichess-Datensatz umfasst etwa 7B Partien, 2,34 TB komprimiert (14 TB unkomprimiert)
Ich frage mich, ob Hadoop bei dieser Größenordnung gewinnen würde
Dafür braucht man dann allerdings auch dediziertes Server-Management
EMR ist auf ein Modell für parallele Verarbeitung ausgelegt, bei dem selten auf Daten zugegriffen wird (1- bis 10-mal pro Tag)