2017-02-03 2 views
1

Meine Python-Anwendung erstellt einen Subprozess für den Upload von AWS CLI S3.Python erstellt einen AWS CLI-Prozess für den S3-Upload und es wird sehr langsam

command = 'aws s3 sync /tmp/tmp_dir s3://mybucket/tmp_dir' 
# spawn the process 
sp = subprocess.Popen(
    shlex.split(str(command)), 
    stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
# wait for a while 
sp.wait() 
out, err = sp.communicate() 

if sp.returncode == 0: 
    logger.info("aws return code: %s", sp.returncode) 
    logger.info("aws cli stdout `{}`".format(out)) 
    return 

# handle error 

/tmp/tmp_dir ist ~ 0,5 GB und enthält etwa 100 Dateien. Upload dauert ~ 25 Minuten, was extrem langsam ist.

Wenn ich AWS-Befehl direkt (ohne Python) ausführen, dauert es weniger als 1 Minute.

Was ist los? Jede Hilfe wird geschätzt.

Antwort

1

Ich bemerkte eine Warnung in der Dokumentation über wait() Nutzung (siehe unten). Anstatt es zu debuggen, warum sollte es nicht umgeschrieben werden, um das Python SDK anstelle von Shell zu aws cli zu verwenden? Wahrscheinlich werden Sie bessere Leistung und saubereren Code erhalten.

https://boto3.readthedocs.io/en/latest/guide/s3.html

Diese Warnung wird Deadlock beim stdout = Rohr und/oder Stderr = Rohr und dem Kindprozess erzeugt an einem Rohr genug Ausgabe mit, so daß sie Blöcke für die OS Rohrpuffer warten, mehr Daten zu akzeptieren, . Verwenden Sie communicate(), um dies zu vermeiden.

https://docs.python.org/2/library/subprocess.html

EDIT3:

hier ist eine Lösung, die ich läuft gerade getestet und es ohne zu blockieren. Es gibt bequeme Methoden, die wait() oder communicate() verwenden, die einfacher zu verwenden sind, wie check_output:

+0

Python SDK bietet derzeit nicht die gleiche Funktionalität. Ich benutze 'sync'. Es wäre wahrscheinlich besser, aber viel zeitaufwendiger. Können Sie ein Beispiel für einen Code angeben, um Pipe Block irgendwie zu vermeiden? Vielen Dank. –

+0

Ah ja, ich sehe was du meinst über sync (rekursive Kopie von Dir) wird nicht implementiert. Hier ist ein Kern, den ich gefunden habe, der nützlich sein könnte: https://gist.github.com/SavvyGuard/6115006#file-botos3upload-py-L30 –

+1

Auch ich redigierte meine Antwort, um eine alternative Verwendung von 'subprocess' vorzuschlagen. –