13 Stimmen

Was ist der schnellste Weg, um eine 10 GB große Datei von der Festplatte zu lesen?

Wir müssen verschiedene Arten von Nachrichten lesen und zählen / ausführen einige Statistiken über eine 10 GB große Textdatei, z.B. eine FIX Motor Protokoll. Wir verwenden Linux, 32-Bit, 4 CPUs, Intel, programmieren in Perl, aber aber die Sprache ist nicht wirklich wichtig.

Ich habe einige interessante Tipps im Buch von Tim Bray gefunden WideFinder-Projekt . Wir haben jedoch festgestellt, dass die Verwendung von Memory Mapping von Natur aus durch die 32-Bit-Architektur begrenzt ist.

Wir haben versucht, mehrere Prozesse zu verwenden, was zu funktionieren scheint schneller, wenn wir die Datei parallel mit 4 Prozessen auf auf 4 CPUs. Das Hinzufügen von Multi-Threading verlangsamt es, vielleicht wegen der Kosten für die Kontextumschaltung. Wir haben versucht, die Größe des Threadpools zu ändern, aber das ist immer noch langsamer als einfache Multiprozess-Version.

Der Teil der Speicherzuordnung ist nicht sehr stabil, manchmal ist er dauert 80 Sekunden und manchmal 7 Sekunden bei einer 2 GB großen Datei, vielleicht wegen Seitenfehlern oder etwas, das mit der Nutzung des virtuellen Speichers zusammenhängt. Wie auch immer, Mmap kann nicht über 4 GB auf einem 32-Bit-System skalieren. Architektur.

Wir haben Perl's IPC::Mmap y Sys::Mmap . Nachgeschaut auch mit Map-Reduce beschäftigt, aber das Problem ist wirklich I/O gebunden, die Verarbeitung selbst ist ausreichend schnell.

Daher haben wir uns entschlossen, die grundlegende E/A zu optimieren, indem wir die Puffergröße, Typ usw. zu optimieren.

Kennt jemand ein bestehendes Projekt, bei dem diese Problem in irgendeiner Sprache/Plattform effizient gelöst wurde auf einen nützlichen Link hinweisen oder eine Richtung vorschlagen?

9voto

Hynek -Pichi- Vychodil Punkte 25789

Die meiste Zeit werden Sie I/O gebunden und nicht CPU gebunden sein, also lesen Sie diese Datei durch normales Perl I/O und verarbeiten Sie sie in einem einzelnen Thread. Solange Sie nicht beweisen können, dass Sie mehr E/A-Leistung erbringen können als die Arbeit einer einzelnen CPU, sollten Sie Ihre Zeit nicht mit etwas anderem verschwenden. Jedenfalls sollten Sie sich fragen: Warum um alles in der Welt ist das eine riesige Datei? Warum um alles in der Welt wird sie bei der Erstellung nicht vernünftig aufgeteilt? Die Arbeit würde sich um ein Vielfaches mehr lohnen. Dann könnte man sie in getrennte E/A-Kanäle legen und mehr CPUs verwenden (wenn man nicht irgendeine Art von RAID 0 oder NAS oder ...).

Messen, nicht vermuten. Vergessen Sie nicht, die Caches vor jedem Test zu leeren. Denken Sie daran, dass serielle E/A um ein Vielfaches schneller ist als zufällige.

4voto

nos Punkte 214143

Das hängt davon ab, welche Art von Vorverarbeitung Sie wann durchführen können. Auf einigen Systemen, die wir haben, gzipen wir solche großen Textdateien und reduzieren sie auf 1/5 bis 1/7 ihrer ursprünglichen Größe. Dies ist unter anderem deshalb möglich, weil wir diese Dateien nicht verarbeiten müssen erst Stunden nach ihrer Erstellung verarbeiten müssen, und zum Zeitpunkt der Erstellung haben wir eigentlich keine andere Last auf den Rechnern.

Die Verarbeitung erfolgt mehr oder weniger nach dem Muster von zcat thosefiles | ourprocessing (allerdings über Unix-Sockets mit einem speziell angefertigten zcat). Es tauscht CPU-Zeit gegen Festplatten-I/O-Zeit, und für unser System war das gut Es lohnt sich. Es gibt natürlich eine Menge Variablen, die dies zu einem sehr schlechten Design für ein bestimmtes System machen können.

3voto

Jeff Ferland Punkte 17180

Ich wünschte, ich wüsste mehr über den Inhalt Ihrer Datei, aber da ich nur weiß, dass es sich um Text handelt, klingt dies nach einem hervorragenden MapReduce-Problem.

PS, das schnellste Lesen einer Datei ist ein lineares Lesen. cat file > /dev/null sollte die Geschwindigkeit sein, mit der die Datei gelesen werden kann.

3voto

Jon Onstott Punkte 12928

Vielleicht haben Sie diesen Forumsbeitrag bereits gelesen, aber wenn nicht, dann

http://www.perlmonks.org/?node_id=512221

Es wird beschrieben, wie man Perl verwendet, um dies Zeile für Zeile zu tun, und die Benutzer scheinen zu glauben, dass Perl dazu in der Lage ist.

Oh, ist es möglich, die Datei von einem RAID-Array aus zu verarbeiten? Wenn Sie mehrere gespiegelte Festplatten haben, kann die Lesegeschwindigkeit verbessert werden. Der Wettbewerb um die Festplattenressourcen könnte der Grund dafür sein, dass Ihr Versuch mit mehreren Threads nicht funktioniert.

Ich wünsche Ihnen viel Glück.

2voto

Paul Nathan Punkte 38618

Haben Sie daran gedacht, die Datei zu streamen und interessante Ergebnisse in eine sekundäre Datei herauszufiltern? (Wiederholen Sie den Vorgang, bis Sie eine Datei mit überschaubarer Größe haben).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X