Bei großen Datenauswertungen, die mehrere GB betreffen, gelangt man schnell mal an seine persönlichen aber auch technischen Grenzen. Bei toscom besitzen wir viele Datenbanken, wobei eine nicht nur dadurch hervorsticht, weil sie 40 GB umfasst, sondern auch weil sie aus vielen einzelnen CSV-Dateien besteht. Nun gilt es bei dieser besonders großen Datenbank, eine Reihe von Auswertung durchzuführen.
Da dieses Vorhaben auf herkömmlichen Weg sehr umständlich und zeitintensiv ist, haben wir uns entschieden, die rohen Daten in das JSON-Format zu konvertieren und danach in eine Elasticsearch-Datenbank zu importieren.
Auch wir standen dabei vor einigen Herausforderungen...
Der erste Versuch war noch etwas blauäugig. Einfach ein schlampiges Ruby-Script welches alle Dateien nacheinander einliest, die Daten in das JSON-Format konvertiert, diese dann in ein Array speichert und am Ende dann das Array durchgeht und die Daten in die Elasticsearch-Datenbank importiert.
Das Script war natürlich viel zu langsam. Ein Import dieser riesigen Datenmengen hätte unsere besten Jahre vergeudet.
Die ganzen Daten erst in ein Array zu speichern war natürlich keine gute Idee. Das kann gar nicht performen. Also wurde das Script angepasst und so optimiert, dass der Zwischenspeicherschritt wegfällt.
Das Script lief dann wesentlich besser. Aber immer noch viel zu langsam.
Ein einziger Prozess der Daten von der Festplatte liest, diese verarbeitet und danach über das Netzwerk in die Datenbank schreibt, ist möglicherweise zu wenig. Deswegen haben wir das Script so umgeschrieben, dass es nicht mehr alle Dateien selbst im Datenordner durchgeht, sondern die Dateinamen als Parameter übergeben bekommt.
So konnte das Script mit Hilfe von den Programmen "Gnu find” und "Gnu parallel” mehrfach gestartet werden. Die großen "Bremser” sind dabei natürlich zum einen die Festplattenzugriffe und zum anderen der Datenimport, welcher über das Netzwerk zusätzlich Zeit braucht. Zu viele gleichzeitige Zugriffe auf die Festplatte sind kontraproduktiv – zu viele offene Netzwerkverbindungen ebenfalls.
Das Script lief dann schon ziemlich gut und wir entschieden den Import über Nacht durchlaufen zu lassen.
Am nächsten Tag hatte der Import erst 1,5 Millionen Datensätze von insgesamt 1,4 Milliarden importiert. Damit waren wir noch immer weit vom Ziel entfernt.
Das Debugging zeigte, dass jeder einzelne Datensatz mit einem eigenen HTTP-Request zur Datenbank geschoben wird. Ein Request hatte also einen längeren HTTP-Header als eigentlichen Payload. Und es gab leider sehr viele Requests, die relativ langsam aufgebaut wurden.
Wir waren mit der Elasticsearch-Api noch zu wenig vertraut, um bessere Alternativen für Imports zu kennen. So entschieden wir einfach einen "Index-Create”-Call zu verwenden. Die Dokumentation der API machte aber rasch klar, dass der Befehl "Bulk” besser wäre. Dieser soll mehrere "Index-Create”-Calls in einem HTTP-Request packen und verschicken können.
Deshalb wurde das Script erneut umgeschrieben. Es bekam einen Buffer, der eine bestimmte Menge an Datensätzen erst in ein Array speichert, und dieses dann gesammelt in einem HTTP-Request verschickt. Wieder lief das Script parallel und die Anzahl der Datensätze musste erst an die eigene Ressourcenleistung angepasst werden. Der Import performte dann wie gewünscht und es wurden mehrere tausend Requests pro Sekunde abgearbeitet.
Es dauerte leider nicht sehr lange bis die Elasticsearch-Datenbank keine Requests mehr annahm. Diese war nämlich mit den Standardwerten konfiguriert und in der Dokumentation steht folgendes: "The default installation of Elasticsearch is configured with a 1 GB heap. For just about every deployment, this number is usually too small. If you are using the default heap values, your cluster is probably configured incorrectly”. Also wurden noch die Datenbankeinstellungen an die eigenen Resourcen angepasst und optimiert. Der Import lief danach stabil.
Softwareseitig hatten wir nun alles im Griff, aber die Hardware kam dann leider auch noch ins Spiel.
Unser Testserver funktionierte gut, wenn nur ein Benutzer Abfragen durchführte. Sobald aber mehrere Benutzer gleichzeitig auf die Datenbank zugreifen wollten, sackte die Performance ab. Teilweise führte es sogar zum kompletten Absturz der Elasticsearch-Datenbank. Die Wiederherstellung der Datenbank nahm jedes Mal wieder 2 Stunden in Anspruch.
Uns wurde schnell klar, dass wir hier unsere Hardware verbessern müssen. Der neue Server bekam wesentlich mehr RAM und SSD-Festplatten. Nach der Übersiedelung auf den neuen Server funktionierten die Abfragen sehr schnell und die Datenbank war stabil.
Am Anfang war unsere Einstellung: "Wir schieben die Daten schnell mal in die Datenbank”. Aber es sollte wie immer anders kommen.
Wir lernten vor allem das Zusammenspiel von Software und Hardware bei Optimierungsmaßnahmen besser zu verstehen. Kleine Änderungen an den Routinen können Wunder bewirken – zu viel parallelisieren kann jedoch wieder eine IO-Bremse sein.
Die Softwareoptimierung brachte die großen Verbesserungen. Durch Ausprobieren und nachjustieren kamen wir letztendlich zum Durchsatz, der für die relativ schwache Hardware am optimalsten war. Was für einen Benutzer gut funktionierte, war für mehrere gleichzeitige Benutzer der Datenbank allerdings nicht brauchbar. Deshalb mussten wir noch die Hardware verbessern. Das war aber, verglichen zu den anderen Optimierungen, am einfachsten und ging am schnellsten.
Elasticsearch funktioniert nach unserer Erfahrung zwar sehr gut für große Datenbanken, dennoch muss einiges an Zeit und Recherchearbeit investiert werden bis ein gewünschtes Ergebnis erreicht wird.
Seit 2003 machen wir nicht nur Webentwicklern das Leben leichter. Als leidenschaftliche Techniker lieben wir gute Lösungen und als 100% remote Company effiziente Abläufe und Kommunikation.
Lernen Sie uns, unsere Partner und unsere Kunden kennen.
toscom GmbH | Breiteneckergasse 32, 1230 Wien | +43 720 11 66 06 | office@toscom.at
Alle Preisangaben verstehen sich exkl. MwSt.
Aus Gründen der besseren Lesbarkeit wird bei Personenbezeichnungen und personenbezogenen Hauptwörtern auf dieser Website die männliche Form verwendet. Entsprechende Begriffe gelten im Sinne der Gleichbehandlung grundsätzlich für alle Geschlechter. Die verkürzte Sprachform hat nur redaktionelle Gründe und beinhaltet keine Wertung.
It appears you have deactived JavaScript in your browser. This feature is only available with JavaScript turned on. If you don't want your data to be collected, you can still turn on Do Not Track in your browser which is a general setting and is being respected by our Matomo installation.