Effiziente Methode zum Analysieren von 100 MB JSON-Nutzdaten

8

Ich führe alle 12 Stunden einen Cron Job auf meiner Amazon EC2 Micro Instanz aus. Es lädt 118MB-Datei herunter und analysiert sie mit der json-Bibliothek. Dies führt natürlich dazu, dass die Instanz keinen Speicher mehr hat. Meine Instanz hat 416 MB freien Speicher, aber ich führe das Skript auf 6 MB runter und dann wird es von OS getötet.

Ich frage mich, was sind meine Möglichkeiten hier? Ist es möglich, dies effizient über Ruby zu analysieren oder muss ich auf Low-Level-Sachen wie C zurückgreifen? Ich kann eine leistungsfähigere Amazon-Instanz bekommen, aber ich möchte wirklich wissen, ob es möglich ist, dies über Ruby zu tun.

UPDATE: Ich habe yajl angeschaut. Es kann Ihnen json-Objekte geben, während es analysiert, aber das Problem ist, wenn Ihre JSON-Datei nur 1 Wurzelobjekt enthält, dann wird es gezwungen, ALLE Dateien zu analysieren. Mein JSON sieht so aus:

%Vor%

Also wenn ich das tue:

%Vor%

Da ich nur ein Wurzelobjekt habe, wird es den gesamten JSON analysieren. Wenn Obj 1/2/3 root wäre, dann würde es funktionieren, da es mir eins nach dem anderen geben wird, aber mein JSON ist nicht so und es analysiert und verschlingt 500 MB Speicher ...

UPDATE # 2: Hier ist eine kleinere Version der großen 118-MB-Datei (7 MB):

GONE

Es ist analysierbar, ich habe nicht nur ein paar Bytes aus der Datei entfernt, nur damit Sie es als Ganzes sehen. Das Array, das ich suche, ist dies

%Vor%

Danke

    
0xSina 21.12.2012, 16:37
quelle

2 Antworten

6

YAJL implementiert einen Streaming-Parser. Sie können es verwenden, um Ihre JSON on-the-fly zu lesen, so dass Sie den Inhalt so bearbeiten können, wie er hereinkommt, und ihn dann (und die generierten Datenstrukturen davon) verwerfen, nachdem Sie damit fertig sind. Wenn Sie clever sind, werden Sie dadurch unter Ihren Speichergrenzen bleiben.

Bearbeiten: Mit Ihren Daten sind Sie wirklich daran interessiert, Teile des JSON-Objekts zu einem Zeitpunkt herauszuziehen, anstatt das gesamte Objekt zu analysieren. Dies ist wesentlich schwieriger und erfordert, dass Sie Ihren eigenen Parser implementieren. Die Grundlagen sind, dass Sie wollen:

  1. Gehen Sie in das Ereignisarray
  2. Analysieren Sie für jedes Ereignis im Array das Ereignis
  3. Übergeben Sie das analysierte Ereignis an eine Callback-Funktion
  4. Verwerfen Sie das analysierte Ereignis und die Quelleneingabe, um Speicherplatz für das nächste Ereignis freizugeben.

Dies funktioniert nicht mit yajl, da Sie hier mit einem Objekt und nicht mit mehreren Objekten arbeiten. Um es mit yajl arbeiten zu können, müssen Sie den JSON manuell analysieren, um die Grenzen des Ereignisobjekts zu entdecken, und dann jeden Ereignisobjekt-Chunk an einen JSON-Parser zur Deserialisierung übergeben. So etwas wie Ragel könnte diesen Prozess für Sie vereinfachen.

Natürlich wäre es einfacher, Ihre AWS-Instanz zu aktualisieren.

    
Chris Heald 21.12.2012, 16:43
quelle
0

Etwas wie yaji kann den JSON als Stream analysieren

    
ireddick 21.12.2012 16:43
quelle

Tags und Links