如果我在 S3 上有一个包含约 5000 个小文件的目录,有没有办法轻松压缩整个目录并将生成的 zip 文件保留在 S3 上?我需要执行此操作,而不必自己手动访问每个文件。
谢谢!
不,没有灵丹妙药。
(顺便说一句,您必须意识到 S3 中不存在“目录”之类的东西。只有带有路径的对象。您可以获得类似目录的列表,但“/”字符并不神奇 -您可以通过任何您想要的字符获得前缀。)
正如有人指出的,“预压缩”它们可以帮助提高下载速度和附加速度。 (以重复存储为代价。)
如果下载是瓶颈,听起来您正在串行下载。 S3 可以毫不费力地支持对同一对象的 1000 个同时连接。您需要运行基准测试来查看有多少连接是最佳的,因为来自一台机器的太多连接可能会受到 S3 的限制。当每秒进行 1000 个连接时,您可能需要进行一些TCP 调整。
“解决方案”在很大程度上取决于您的数据访问模式。尝试重新安排问题。如果您的单文件下载不频繁,那么将它们一次分组到 S3 中 100 个,然后在需要时将它们分开可能更有意义。 如果它们是小文件,将它们缓存在文件系统上可能是有意义的。
或者将所有 5000 个文件存储为 S3 中的一个大 zip 文件,并使用可以下载 zip 文件的特定范围的“智能客户端”以便为各个文件提供服务可能是有意义的。 (我记得 S3 支持字节范围。)
我同意@BraveNewCurrency 的回答。
您需要自己的服务器才能有效地完成此操作,因为 AWS S3 只是真正意义上的键值存储。
命令行工具将无法工作,因为文件和参数太多。
付费选项
我实际上参与了一个廉价的商业项目,就是这样做的。
它们提供 API 和启动您自己的预配置 EC2 zipper 服务器的选项。
https://s3zipper.com/
https://docs.s3zipper.com
大规模迁移(Terabyte->PB 级)
AWS 雪球
免费选项
您还可以使用以下免费软件包(JavaScript 和 Go(Golang))构建自己的服务器:
https://github.com/orangewise/s3-zip
https://github.com/DanielHindi/aws-s3-zipper
https://github.com/Teamwork/s3zipper
以下内容对我有用:
def ListDir(bucket_name, prefix, file_type='.pgp'):
#file_type can be set to anything you need
s3 = boto3.client('s3')
files = []
paginator = s3.get_paginator('list_objects_v2')
pages = paginator.paginate(Bucket=bucket_name, Prefix=prefix)
for page in pages:
for obj in page['Contents']:
files.append(obj['Key'])
if files:
files = [f for f in files if file_type in f]
return files
def ZipFolder(bucket_name,prefix):
files = ListDir(bucket_name,prefix)
s3 = boto3.client("s3")
zip_buffer = io.BytesIO()
for ind,file in enumerate(files):
file = file.split("/")[-1]
print(f"Processing file {ind} : {file}")
object_key = prefix+file
print(object_key)
with zipfile.ZipFile(zip_buffer, "a", zipfile.ZIP_DEFLATED, False) as zipper:
infile_object = s3.get_object(Bucket=bucket_name, Key=object_key)
infile_content = infile_object['Body'].read()
zipper.writestr(file, infile_content)
s3.put_object(Bucket=bucket_name, Key=prefix + YOUR_ZIP_FILENAME, Body=zip_buffer.getvalue())
您可以尝试在 Windows 上使用 s3browser 应用程序。
如果您想压缩小数据,请使用上面的代码。 否则,如果数据量很大,必须尝试 ec2,否则不要做任何愚蠢的事情! :D