Halihallo Andreas
Komme gleich zu dem von dir gesagten, aber ich nutze den Subthread gleich dazu eine
aktuelle Problematik vorzustellen und hoffe auf etwas Input der Forumer:
Ich habe eine Apache-Access-Log vorliegen, ca. 2GB gross. Nun gilt es aus dieser Datei
eine neue Datei zu transformieren, welche die _unterschiedlichen_ (aus der Ur-
sprungsdatei extrahierten) IP's abbildet. Erschwerend kommt hinzu, dass die zu
IP's nur von einem bestimmten Zeitfenster extrahiert werden sollen. Programmiersprache
vorzugsweise C (evtl. Perl).
Frage gleich hier: Wie würdet ihr das möglichst performant umsetzen?
Meine Gedanken:
Die access-log ist per Definition schon nach der Zeit indiziert, nur sind die Datensätze
nicht fixer Länge. Ich dachte mir, dass ich trotz dieses Umstandes die Datei als eine
Datei fixer Datensatzlänge interpretiere und einen Buffer von 32kb anlege. Wenn es nun
darum geht eine bestimmte Zeit zu selektieren, iteriere ich wie in einem B-Baum über
die Datei, untersuche den aktuell eingelesenen Buffer auf Newlines und lese alles danach
in die struct log_entry ein. Falls das extrahierte Datum kleiner als das zu suchende ist,
wird die nächste Hälfte selektiert, die vorherige wenn das Datum grösser ist. So finde
ich in dem access_log in etwa log(n)-Zeit das gewünschte Datum (nicht n/2, wenn ich alle
Daten extrahieren würde). Wenn ich die Position des Start-Entries und des End-Entries
gefunden habe iteriere ich über die eingeschlossenen log-Entries und extrahiere die IP's.
Über ein Look-Back-Array von 10'000 IP's finde ich die unterschiedlichen[1] und
speichere sie in der Ausgabedatei ab.
Meine Frage:
Habt Ihr mir vielleicht Anregungen? - Verbesserungsvorschläge? - Anmerkungen?
[1] mit einigermassen kleiner Fehlerrate, die tolerabel ist. Alles kleiner 5% Fehler ist
für die Aufgabenstellung akzeptabel. Die 5% Fehler bezihen sich auf die extrahierten
IP's von einem Tag. Die 10'000 ist IMHO ausreichend, denn viel mehr werden in einem
Tag gar nicht gespeichert. Mir ist bewusst, dass die IP's nicht staatisch zugewiesen
werden, die IP's werden zu bestimmten Zeiten aufgelöst und somit macht es keinen
Sinn, wenn man mehrmals die selbe IP auflöst, deshalb die Extraktion
unterschiedlicher IP's.
--- zu dir :-) ---
Nochmal wegen meines Algorithmus-problems von vor kurzem, ich hatte das noch Stunden später weiter probiert zu optimieren, es ist aber eher schlechter als besser geworden, als ich dann auf einmal durch Umwandlung in INT dachte es geschafft zu haben, da auf einmal 10 mal so schnell, da merjte ich dann nachdem ich das lange Posting fast abgeschickt hätte, dass die Zahlen für INT zu lang waren und in wirklichkeit Negative Zahlen waren die immer sofort beim 1. Daatensatz vertig waren, naja, dann war ich so genervt dfass ich keine Lust mehr hatte, und dann war der Thread irgendwann weg, naja, ich weiß nicht, mit PHP scheint das irgendwie nicht möglich, was mich wundert, ich habe am Ende direkt mit den Pointern gearbeitet, aber das war halt noch langsamer, naja.
Verflixte Angelegenheit, was? :-)
Da ich seit dem 30.04 auch unter den C-Programmierer-Nebies verweile hatte ich mich
gleich mal an eine Lösung über C gesetzt. Das Ergebnis: Durchschnittlich 0.233ms für
das Durchsuchen des ganzen Datenbestandes (hatte einfach als Such-IP die letzte
angegeben). Jedoch glaube ich nicht, dass das relevant ist, da ich 1000 mal iteriert
habe und jedesmal die Datei geöffnet und geschlossen habe => wurde bestimmt auch
gecached. Habe auch versuche nur einmal zu iterieren, da bin ich auf 0.3-0.4ms
gekommen, aber da bin ich mir nicht sicher, wie genau diese Zeitangaben gemessen werden.
(hatte die Datenstruktur noch stark optimiert:)
32723878932747239874987DE
32723878932747239874987US
...
Hm. Habe als Input auch über Perl transformiert und eine Datei für den wahlfreien
Zugriff mit fixer Record-Länge erstellt; vereinfacht das Leben mit C :-)
Und zum Index, ich _habe_ eine Index über beide IP-Spalten einzelnd, oder beide zusammen gelegt, es brachte nichts. Aber der Cache hat auch glaube ich mein Bild grob verfälscht, denn HEAP war nach langer Pause _erheblich_ schneller als MyISAM.
Ja, eigentlich mag ich das Caching vom OS nicht, das verhindert ein einfaches
Benchmarking... :-((
Viele Grüsse
Philipp