Python 为 S3 上传生成了 AWS CLI 进程,并且它变得非常慢



我的 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分钟的时间。

怎么了?任何帮助,不胜感激。

我在文档中注意到有关wait()用法的警告(见下文(。但是,与其调试它,为什么不重写它以使用 Python 开发工具包而不是 shell 到 aws cli?也许你会得到更好的性能和更干净的代码。

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

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

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

编辑3:

这是我刚刚测试的解决方案,它可以运行而不会阻塞。有一些方便的方法在引擎盖下使用 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

相关内容

  • 没有找到相关文章

最新更新