簡體   English   中英

如何在 Python 中高效地將小文件上傳到 Amazon S3

[英]How to upload small files to Amazon S3 efficiently in Python

最近,我需要實現一個程序,以盡快將駐留在 Amazon EC2 中的文件上傳到 Python 中的 S3。 文件大小為30KB。

我嘗試了一些解決方案,使用多線程、多處理、協程。 以下是我在 Amazon EC2 上的性能測試結果。

3600(文件數量)*30K(文件大小)~~105M(總計)--->

       **5.5s [ 4 process + 100 coroutine ]**
       10s  [ 200 coroutine ]
       14s  [ 10 threads ]

代碼如下所示

用於多線程

def mput(i, client, files):
    for f in files:
        if hash(f) % NTHREAD == i:
            put(client, os.path.join(DATA_DIR, f))


def test_multithreading():
    client = connect_to_s3_sevice()
    files = os.listdir(DATA_DIR)
    ths = [threading.Thread(target=mput, args=(i, client, files)) for i in range(NTHREAD)]
    for th in ths:
        th.daemon = True
        th.start()
    for th in ths:
        th.join()

對於協程

client = connect_to_s3_sevice()
pool = eventlet.GreenPool(int(sys.argv[2]))

xput = functools.partial(put, client)
files = os.listdir(DATA_DIR)
for f in files:
    pool.spawn_n(xput, os.path.join(DATA_DIR, f))
pool.waitall()

對於多處理 + 協程

def pproc(i):
    client = connect_to_s3_sevice()
    files = os.listdir(DATA_DIR)
    pool = eventlet.GreenPool(100)

    xput = functools.partial(put, client)
    for f in files:
        if hash(f) % NPROCESS == i:
            pool.spawn_n(xput, os.path.join(DATA_DIR, f))
    pool.waitall()


def test_multiproc():
    procs = [multiprocessing.Process(target=pproc, args=(i, )) for i in range(NPROCESS)]
    for p in procs:
        p.daemon = True
        p.start()
    for p in procs:
        p.join()

機器配置為Ubuntu 14.04,2個CPU(2.50GHz),4G內存

達到的最高速度約為19Mb/s (105 / 5.5) 總的來說,速度太慢了。 有什么辦法可以加快速度? stackless python 可以做得更快嗎?

此處提供了使用 Python boto SDK 並行上傳到 Amazon S3 的示例:

除了自己編寫代碼,您還可以考慮調用AWS 命令​​行界面 (CLI) ,它可以並行上傳。 它也是用 Python 編寫的並使用 boto。

我最近需要將大約 5 TB 的小文件上傳到 AWS,並通過在 ~/.aws/config 文件中設置更高的“max_concurrent_request”值來達到 ~750Mbits(每台服務器 1 Gb 連接)的完整網絡帶寬。

我通過 bash for 循環啟動多個上傳作業並將這些作業發送到不同的服務器,從而進一步加快了進程。

我也試過 python 例如。 s3-parallel-put,但我認為這種方法更快。 當然,如果文件太小,應該考慮:壓縮 --> 上傳到 EBS /S3 並在那里解壓

這是一些可能有幫助的代碼。

$cat .aws/config 
[default]
region = eu-west-1
output = text
s3 =
    max_concurrent_requests = 100

比啟動多個 aws 復制作業,例如:

for folder in `ls`; do aws s3 cp $folder s3://<bucket>/$folder/whatever/; done

我和你有同樣的問題。 我的解決方案是將數據發送到 AWS SQS,然后使用 AWS Lambda 將它們保存到 S3。

所以數據流看起來:app -> SQS -> Lambda -> S3

整個過程是異步的,但接近實時:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM