【发布时间】:2020-10-12 21:16:55
【问题描述】:
我正在尝试将大约 5000 万个文件和 15TB 的总大小从一个 s3 存储桶复制到另一个存储桶。 有 AWS CLI 选项可以快速复制。但就我而言,我想放置一个过滤器和日期范围。所以我想用boto3来写代码。
源桶输入结构:
Folder1 File1 - Date1 File2 - Date1 Folder2 File1 - Date2 File2 - Date2 Folder3 File1_Number1 - Date3 File2_Number1 - Date3 Folder4 File1_Number1 - Date2 File2_Number1 - Date2 Folder5 File1_Number2 - Date4 File2_Number2 - Date4
因此,目的是使用日期范围(Date2 到 Date4)从每个文件夹中复制所有以“File1”开头的文件。 date(Date1, Date2, Date3, Date4) 为文件修改日期。
输出将具有日期键分区,并且我使用 UUID 来保持每个文件名的唯一性,因此它永远不会替换现有文件。因此,具有相同日期(文件修改日期)的文件将位于同一文件夹中。
目标桶会有输出:
Date2 File1_UUID1 File1_Number1_UUID2 Date3 File1_Number1_UUID3 Date4 File1_Number2_UUID4
我已经编写了代码,使用 boto3 API 和 AWS 胶水来运行代码。但是 boto3 API 每天复制 50 万个文件。
代码:
s3 = boto3.resource('s3', region_name='us-east-2', config=boto_config)
# source and target bucket names
src_bucket_name = 'staging1'
trg_bucket_name = 'staging2'
# source and target bucket pointers
s3_src_bucket = s3.Bucket(src_bucket_name)
print('Source Bucket Name : {0}'.format(s3_src_bucket.name))
s3_trg_bucket = s3.Bucket(trg_bucket_name)
print('Target Bucket Name : {0}'.format(s3_trg_bucket.name))
# source and target directories
trg_dir = 'api/requests'
# source objects
s3_src_bucket_objs = s3_src_bucket.objects.all()
# Request file name prefix
file_prefix = 'File1'
# filter - start and end date
start_date = datetime.datetime.strptime("2019-01-01", "%Y-%m-%d").replace(tzinfo=None)
end_date = datetime.datetime.strptime("2020-06-15", "%Y-%m-%d").replace(tzinfo=None)
# iterates each source directory
for iterator_obj in s3_src_bucket_objs:
file_path_key = iterator_obj.key
date_key = iterator_obj.last_modified.replace(tzinfo=None)
if start_date <= date_key <= end_date and file_prefix in file_path_key:
# file name. It start with value of file_prefix.
uni_uuid = uuid.uuid4()
src_file_name = '{}_{}'.format(file_path_key.split('/')[-1], uni_uuid)
# construct target directory path
trg_dir_path = '{0}/datekey={1}'.format(trg_dir, date_key.date())
# source file
src_file_ref = {
'Bucket': src_bucket_name,
'Key': file_path_key
}
# target file path
trg_file_path = '{0}/{1}'.format(trg_dir_path, src_file_name)
# copy source file to target
trg_new_obj = s3_trg_bucket.Object(trg_file_path)
trg_new_obj.copy(src_file_ref, ExtraArgs=extra_args, Config=transfer_config)
# happy ending
我们是否有任何其他方法可以使其快速或任何替代方法来复制这种目标结构中的文件?您对改进代码有什么建议吗?我正在寻找一些更快的方法来复制文件。您的意见将很有价值。谢谢!
【问题讨论】:
-
你能从你的 python 脚本中运行
aws s3 syncCLI 作为命令吗? -
@Marcin 同步的挑战是在目标存储桶中创建一个日期键目录并排除源目录(Folder1、Folder2、..) 4. aws s3 sync s3://staging1 s3:/ /staing2/api/requests --exclude "" --include "*/File1"
-
查看rclone.org 工具
-
我已经成功使用 S3 Batch Operations ... 简而言之;您的逻辑存在于 Lambda 函数中,而 S3 本身为您进行编排,为每个对象调用 lambda……它负责遍历每个对象、调用 lambda、收集结果、重试等……它不快,但很强大docs.aws.amazon.com/AmazonS3/latest/dev/batch-ops-basics.html
标签: amazon-web-services amazon-s3 boto3 aws-cli boto