Python为S3上传产生AWS CLI流程,它变得非常慢

时间:2017-02-03 20:06:33

标签: python amazon-web-services amazon-s3

我的Python应用程序为AWS CLI S3上传创建子流程。

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约为0.5Gb,包含大约100个文件。 上传过程大约需要25分钟,这非常慢。

如果我直接运行AWS命令(没有Python),则只需不到1分钟。

出了什么问题?任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

我在文档中发现了有关wait()用法的警告(见下文)。但是,为什么不重写它来使用Python SDK而不是shell来解决这个问题?可能你会获得更好的性能和更清晰的代码。

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

  

警告当使用stdout = PIPE和/或stderr = PIPE时,这将导致死锁,并且子进程会为管道生成足够的输出,以阻止等待OS管道缓冲区接受更多数据。使用communic()来避免这种情况。

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

EDIT3:

这是我刚刚测试的解决方案,它可以无阻塞地运行。有一些方便的方法,使用wait()或communication(),更容易使用,如check_output:

#!/usr/bin/env python
import subprocess
from subprocess import CalledProcessError

command = ['aws','s3','sync','/tmp/test-sync','s3://bucket-name/test-sync']
try:
    result = subprocess.check_output(command)
    print(result)
except CalledProcessError as err:
    # handle error, check err.returncode which is nonzero.
    pass