Verarbeitung von sehr großen Datenmengen

deostift

Erfahrenes Mitglied
Hallo zusammen,

ich nutze zur Zeit eine klassische Installation aus Apache 2 sowie MySQL 5.0.37 und PHP 5.0.3.

In der Datenbank habe ich eine sehr große Anzahl an Messungen gespeichert und es kommen jede Nacht neue Daten in Form von XML Files (werden per FTP hochgeladen) hinzu.

Diese müssten mit einem Script verarbeitet werden, sprich: Bewertet nach speziellen Regeln (valide oder nicht), Umrechnungen (Normierung), Summenbildungen etc. und eben dann in die MySQL Datenbank abspeichern.

Die Frage ist nun, wie gehe ich das mit PHP an, damit ich ein schnelles, zügiges Verarbeitungs-Script habe. Stichworte Speicherverbrauch und Laufzeit. Häppchenweise die Daten einlesen? Wie groß sollten hierbei die jeweiligen Pakete sein? Timeouts muss ich auf der Konsole nicht fürchten oder?

Anderes aber gleiches Problem ist auch ein Aufarbeiten von bestehenden Datentabellen in MySQL. Es ist nicht selten dass ich hier Tables mit weit mehr als 300.000 Einträgen durchrechnen muss. Also nach bestimmten Kriterien filtern und dann Merkmale setzen.

Also kurz: Ich arbeite schon eine Zeit lang mit PHP aber musste mich bisher nie um die Performance kümmern. Bisher waren es immer nur Browser-Anfragen eben kurz verarbeiten und gut ist. Allerdings keine Tonnen an Daten verarbeiten ;-/

Danke Euch für Tipps und Herangehensweisen.

Mikk
 
> Häppchenweise die Daten einlesen
Wäre ein Ansatz, denn ich aber nur bei CSV-Dateien so mache.
Bei XML ist das alles gar nicht so lustig, weil man diese erst komplett einlesen muss :-(
Ok, kann mich auch irren, aber wüsste nicht, wie man effektiv eine XML Zeilenweise einlesen könnte, ohne das dabei Daten verloren gehen.

Um Timeouts zu verhindern, wickel ich solche Geschichten generell über Cronjob ab.
Über die Browser-Ebene werden nur kleine Stücke eingelesen.

Um die Daten dann in eine DB einzubinden benutze ich mysql_info().
Hintergedanke dabei ist, dass die Daten erst geprüft werden müssen, ob sie schon in der DB enthalten sind.
Falls nicht sollen sie importiert werden.
Hier kann die Performance mächtig in die Knie gehen, wenn die DB schon 1.000.000 Datensätze hat :-)

Im Prinzip benutze ich hier nur ein Trick.
Es wird sofort ein UPDATE versucht, mit mysql_info() wird dann abfragt, wieviel Datensätze das betrfoffen hat (falls, dann immer nur 1).
Liefert mysql_info = 0, dann werden die Daten importiert.

Diese Lösung war wesentlich schneller, als ein extra Query zu setzen, und ständig die DB abzufragen, ob der Datensatz schon vorhanden ist oder nicht.

Aus Erfahrung kann ich nur sagen, dass das verarbeiten von großen XML-Files sehr viel Speicher verbraucht (Funktionen wie DOM_XML, oder Simple_xml etc..).
Wie man dennoch damit schnell arbeiten kann (im Vergleich zu CSV), habe ich bisher noch nicht heraus bekommen :-)
 
Okay ich danke Dir :)

Und ja ... die Datenbank ist richtig fett :) habe im Moment 400 Millionen Datensätze auf 200 Tables verteilt, was ca. 30 Gigabyte Daten gespricht.
 
Uff... jetzt nichts zum Scripten aber da würde ich dir / euch vorschlagen nicht MySQL zu nutzen sondern Oracle oder SQL. Mit ein wenig Perle knowhow bist du da sicherer und schneller als mit PHP und MySQL.

Oracle und SQL sind einfach "klüger" in sachen DB und bei so grossen Datenbanken würde ich es mir überlegen.

Nur ein Tipp


Greez
 
Hallo Malaxo,

danke für Dein Feedback. Sicherlich sind SQL Server oder Oracle besser aber halt nicht ganz so günstig ;)

Perl mag sicherlich bessere (schnellere?!) String-Operationen haben, aber dass es wesentlich schneller ist, kann ich im Moment nicht glauben.

Und so nebenbei: MySQL ist eigentlich weniger das Problem und kommt mit den Datenmengen erstaunlich gut zurecht.

Mein Problem liegt eher in der Verarbeitung und da wird sich Perl und PHP sicherlich nicht viel schenken. Wir haben im Moment ein Perl Script laufen das die XML Dateien verarbeitet, aber es liest diese komplett ein und verbraucht massiv Speicher.

Was ich benötige sind Hinweise wie ich die Verarbeitung grundsätzlich aufbauen sollte.

Aber ich denke mal hier hilft wohl nur "learning by doing" .. also mit der Stoppuhr daneben sitzen und Varianten durchprobieren :(
 
Hallo,

erstmal zum Thema MySql, das ist sehr wohl für große Datenmengen geeignet, wir hatte bei uns mal jemanden direkt von MySql in der Firma, der meinte das Mysql locker mit 1TB umgehen kann zwischen 1 und 10 TB wirds dann langsam interessant und wenn man es doch mal geschaft hat über 10TB zu kommen kann man mal nachdenken zu Oracle zu gehen, das erstmal dazu.

Ich selbst habe auch relativ große Datenmengen, sprich gut 40 Mio Datensätze, 37 Mio davon in einer Tabelle.
Ich bekomme ebenfalls XMLs die im Schnitt zwischen 300 und 400 MB groß sind.
Diese Kann ich natürlich nicht Komplett einlesen und durch ne Deserialisierer jagen, da würde unser Server nich mitmachen *g*, die Erfahrung hat gezeigt das der Speicherverbauch mit dem Faktor 20 benutzt wird.

Also hier die Lösung:

Fang an das XML einzulesen, du musst natürlich Wissen mit was ein Datensatz anfängt und mit was er aufhört
lies also ein bis du zb ein <row> findest, dannach liest du solange weiter ein bis du ein </row> findest, ich habe da immer so 1000 Zeichen eingelesen und dadrin gesucht...
Hast du nun eine Zeile Komplett dann baust du dir dein Query zusammen und speicherst es in eine Datei. Das machst du solange bis du durch bist und am Ende schießt du die Datei gegen deine DB und fertig.
Dadurch hab ichs geschafft das dass XML ziehen länger dauert als es zu verarbeiten und anschließend in die DB zu schieben. ;-)
zeitersparnis ca. eine Stunde *g*
btw. das script verbraucht Max 10MB ^^

Viel erfolg.

Gruß
King of Darkness
 
Zurück