从S3存储桶下载300万个对象的最快方法

Jag*_*dha 29 python linux amazon-s3 boto eventlet

我已经尝试过使用Python + boto +多处理,S3cmd和J3tset,但是他们都在苦苦挣扎.

任何建议,也许是你一直在使用的现成脚本或我不知道的另一种方式?

编辑:

eventlet + boto是一个有价值的解决方案,如下所述.在http://web.archive.org/web/20110520140439/http://teddziuba.com/2010/02/eventlet-asynchronous-io-for-g.html找到了一篇很好的活动参考文章

我已经在下面添加了我正在使用的python脚本.

Jag*_*dha 33

好吧,我想出了一个基于@Matt Billenstien的提示的解决方案.它使用eventlet库.第一步是最重要的(猴子修补标准IO库).

使用nohup在后台运行此脚本,您已完成设置.

from eventlet import *
patcher.monkey_patch(all=True)

import os, sys, time
from boto.s3.connection import S3Connection
from boto.s3.bucket import Bucket

import logging

logging.basicConfig(filename="s3_download.log", level=logging.INFO)


def download_file(key_name):
    # Its imp to download the key from a new connection
    conn = S3Connection("KEY", "SECRET")
    bucket = Bucket(connection=conn, name="BUCKET")
    key = bucket.get_key(key_name)

    try:
        res = key.get_contents_to_filename(key.name)
    except:
        logging.info(key.name+":"+"FAILED")

if __name__ == "__main__":
    conn = S3Connection("KEY", "SECRET")
    bucket = Bucket(connection=conn, name="BUCKET")

    logging.info("Fetching bucket list")
    bucket_list = bucket.list(prefix="PREFIX")

    logging.info("Creating a pool")
    pool = GreenPool(size=20)

    logging.info("Saving files in bucket...")
    for key in bucket.list():
        pool.spawn_n(download_file, key.key)
    pool.waitall()
Run Code Online (Sandbox Code Playgroud)

  • 最后添加了```pool.waitall()```,否则代码什么也没做,并在任何下载真正完成之前退出. (3认同)
  • 注意,如果我不在每个greenlet中创建连接,我就遇到了问题.您是否可以使用此表下载所有对象? (2认同)
  • 不,我也有问题.下载4000个对象后,它停止工作.我没有时间调试它,所以我最终从shell脚本中为每个文件使用*s3cmd get*.我将S3上的文件名列表分成了几组,并且每次运行7-8套脚本(所以我在任何时间点都有7-8*s3cmd获取*请求).使用boto的*bucket.list()*方法获取文件列表,然后使用*split*shell命令创建大小相同的集合.这可能比eventlet方法消耗更多的CPU,但它很简单并完成工作. (2认同)

Mat*_*ein 5

使用eventlet为您提供I/O并行性,编写一个简单的函数来使用urllib下载一个对象,然后使用GreenPile将其映射到输入URL列表 - 一个包含50到100个greenlet的堆应该...