![](/img/trans.png)
[英]Move files between folder on Amazon S3 using boto3 ( The specified bucket does not exist error)
[英]Fastest way to move objects within an S3 bucket using boto3
我需要將所有文件從 S3 中的一個前綴復制到同一存儲桶中的另一個前綴。 我的解決方案是這樣的:
file_list = [List of files in first prefix]
for file in file_list:
copy_source = {'Bucket': my_bucket, 'Key': file}
s3_client.copy(copy_source, my_bucket, new_prefix)
然而,我只移動了 200 個小文件(每個 1 kb),這個過程最多需要 30 秒。 一定有可能做得更快嗎?
我會並行執行。 例如:
from multiprocessing import Pool
file_list = [List of files in first prefix]
print(objects_to_download)
def s3_coppier(s3_file):
copy_source = {'Bucket': my_bucket, 'Key': s3_file}
s3_client.copy(copy_source, my_bucket, new_prefix)
# copy 5 objects at the same time
with Pool(5) as p:
p.map(s3_coppier, file_list)
所以你有一個函數需要調用一堆東西,所有這些東西都是相互獨立的。 您可以嘗試多處理。
from multiprocessing import Process
def copy_file(file_name, my_bucket):
copy_source = {'Bucket': my_bucket, 'Key': file_name}
s3_client.copy(copy_source, my_bucket, new_prefix)
def main():
file_list = [...]
for file_name in file_list:
p = Process(target=copy_file, args=[file_name, my_bucket])
p.start()
然后它們都可以(大約)同時開始,而不必等待最后一個文件完成。
所以我做了一個小實驗,將 500 個 1kB 小文件從同一個 S3 存儲桶移動到同一個存儲桶 3,從 AWS 中的 Lambda(1024 MB ram)運行。 我對每種方法都做了 3 次嘗試。
嘗試 1 - 使用 s3_client.copy:31 - 32 秒
嘗試 2 - 使用 s3_client.copy_opbject:22 - 23 秒
嘗試 3 - 使用多處理、池(上面的答案):19 - 20 秒
有沒有可能做得更快?
我知道這是一篇舊帖子,但也許有人會像我一樣來到這里,想知道最優雅的方式 (IMO) 是什么。
如果我們使用awswrangler
PyPi package,我們可以獲得良好的性能並以零努力並行執行。
根據os.cpu_count()
返回的內容,它將盡可能多地利用線程。
import os
import botocore
import awswrangler as wr
import boto3
S3 = boto3.resource("s3")
bucket_name = os.environ["BUCKET_NAME"]
BUCKET = S3.Bucket(bucket_name)
def copy_from_old_path():
source_prefix = "some_prefix"
new_prefix = "some_new_prefix"
objects = BUCKET.objects.filter(Prefix=source_prefix)
keys_list = [obj.key for obj in objects]
bucket_uri = f"s3://{bucket_name}"
full_paths_list = [f"{bucket_uri}/{key}" for key in keys_list] # key includes the source_prefix also
source_path = f"{bucket_uri}/{source_prefix}/"
target_path = f"{bucket_uri}/{new_prefix}/"
wr.s3.copy_objects(full_paths_list, source_path, target_path)
if __name__ == "__main__":
copy_from_old_path()
當從 Macbook M1 Pro(32 GB 內存)本地運行時,我花了大約 20 分鍾來復制 24.5 MB 的 4,475 個鑲木地板文件(每個大約 7 KB)。 在運行之前不要忘記在 CLI 中導出 AWS 憑證,並導出保存存儲桶名稱的環境變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.