压缩 S3 上的整个目录

问题描述 投票:0回答:5

如果我在 S3 上有一个包含约 5000 个小文件的目录,有没有办法轻松压缩整个目录并将生成的 zip 文件保留在 S3 上?我需要执行此操作,而不必自己手动访问每个文件。

谢谢!

amazon-web-services amazon-s3 s3cmd
5个回答
18
投票

不,没有灵丹妙药。

(顺便说一句,您必须意识到 S3 中不存在“目录”之类的东西。只有带有路径的对象。您可以获得类似目录的列表,但“/”字符并不神奇 -您可以通过任何您想要的字符获得前缀。)

正如有人指出的,“预压缩”它们可以帮助提高下载速度和附加速度。 (以重复存储为代价。)

如果下载是瓶颈,听起来您正在串行下载。 S3 可以毫不费力地支持对同一对象的 1000 个同时连接。您需要运行基准测试来查看有多少连接是最佳的,因为来自一台机器的太多连接可能会受到 S3 的限制。当每秒进行 1000 个连接时,您可能需要进行一些TCP 调整

“解决方案”在很大程度上取决于您的数据访问模式。尝试重新安排问题。如果您的单文件下载不频繁,那么将它们一次分组到 S3 中 100 个,然后在需要时将它们分开可能更有意义。 如果它们是小文件,将它们缓存在文件系统上可能是有意义的。

或者将所有 5000 个文件存储为 S3 中的一个大 zip 文件,并使用可以下载 zip 文件的特定范围的“智能客户端”以便为各个文件提供服务可能是有意义的。 (我记得 S3 支持字节范围。)


14
投票

我同意@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


1
投票

以下内容对我有用:

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())


0
投票

您可以尝试在 Windows 上使用 s3browser 应用程序。


0
投票

如果您想压缩小数据,请使用上面的代码。 否则,如果数据量很大,必须尝试 ec2,否则不要做任何愚蠢的事情! :D

© www.soinside.com 2019 - 2024. All rights reserved.