7

Ich ersuche Daten von einer externen API und schreibe sie direkt in eine Cloud Storage-Datei. Die Daten schreiben zwar gut, aber wenn ich skaliere, stoße ich auf Speicherprobleme und drücke die 1024-MB-Grenze für die GAE-Instanzen. GAE Memory Leaks beim Schreiben in Cloud Storage, kann ich stattdessen streamen?

Dies sind die kritischen Fehler, die ich erhalten:

Exceeded soft private memory limit of 1024 MB with 1425 MB after servicing 46 requests total 

Dies ist eine Zusammenfassung des Codes verwende ich:

import cloudstorage as gcs 
import urllib2 

# Example file path 
filePath = '/bucket/dir/file.gzip' 

def deferrableTask(filePath, api_url, post_body): 
    with gcs.open(filePath, 'w') as f: 
     request = urllib2.Request(api_url, post_body) 
     try: 
     response = urllib2.urlopen(request, timeout = 600) 
     except urllib2.HTTPError, e: 
     raise customError(e) 
     else: 
     while True: 
      chunk = response.read(16 * 1024) 
      if not chunk: break 
      f.write(chunk) 
     f.close() 
     del f 
    gc.collect() 

Die Aufgabe oben gemacht wird deferrable mit Aufgabenlisten zu sein. Es könnte bis zu 40 von ihnen gleichzeitig in einer Warteschlange laufen. In meinem app.yaml habe ich die folgenden Einstellungen:

instance_class: F4_1G 
automatic_scaling: 
    max_concurrent_requests: 4 

Dieser Code für das Schreiben von api Daten zu Cloud-Speicher arbeitet. Wenn ich anfange, mehrere hundert dieser Anfragen zu machen, bekomme ich Probleme mit dem Speicher.

Die angeforderten GZIP-Dateien haben eine Größe von 300 KB bis 10-20 MB, und ich dachte, dass durch die Verwendung von gc.collect() in Kombination mit der Begrenzung der Anzahl gleichzeitiger Instanzenanforderungen Speicherverluste zu reduzieren. Mir ist auch bewusst, dass urllib2 nur ein Wrapper für die Urlfetch der App-Engine ist, aber das Holen ist nicht das Problem, es ist die Skalierung.

Wie viel Speicher belegt die Variable f? Ist es möglich, direkt in Google Cloud Storage zu streamen, anstatt die Daten zuerst in den Instanzenspeicher zu laden?

+0

Ich habe das gleiche Problem. Unsere Web-App versucht, eine Datei in GCS zu schreiben, die nur 20 MB groß ist, und die Anfrage schlägt ziemlich häufig mit folgendem Fehler fehl: "Überschreitet das Limit des privaten Speichers von 128 MB mit 216 MB nach der Wartung von 0 Anfragen insgesamt." –

+0

Ich verwende keine Skalierung. Ich benutze auch keine F4_1G Maschinen, ich benutze die Standard F1s. Ich glaube nicht, dass dieses Problem etwas mit Instanzklassen oder Skalierungseinstellungen zu tun hat. Ich erhalte die Speicherfehler auf einer einzelnen F1-Instanz, nachdem ich nur eine Anfrage versucht habe. Irgendetwas stimmt nicht mit der 'cloudstorage'-Lib? –

+0

Ich denke, das ist der Fall. Selbst bei der erzwungenen Speicherbereinigung behalten die Instanzen zu viele Aufgaben im Speicher, was zu der Annahme führt, dass mit App Engine selbst etwas nicht stimmt. Die einzige Aufgabe bestand darin, die fehlgeschlagenen Aufgaben in eine Wiederholungswarteschlange zu senden, um sie später erneut zu versuchen, aber selbst dann würden einige größere Aufgaben immer noch nicht abgeschlossen werden. – Jabberwockey

Antwort

0

Es gibt eine Möglichkeit, dass Sie die Daten direkt aus der externen App in das GCS schreiben können. Dazu müssen Sie die ACL des Buckets in public ändern und dann mit Hilfe der Cloud Storage API Daten in die Eimer.

Auch lassen Sie mich wissen, haben Sie irgendwelche Details der automatischen Skalierungskonfiguration in Ihrer Frage vermisst. Wenn ja, dann geben Sie bitte diese Details an.

+0

Die Daten sind vertraulich und proprietär, dh der Bucket kann niemals veröffentlicht werden. – Jabberwockey

Verwandte Themen