Zip весь каталог на S3

Если у меня есть каталог с ~5000 маленьких файлов на S3, есть ли способ легко заархивировать весь каталог и оставить полученный ZIP-файл на S3? Мне нужно сделать это без необходимости вручную обращаться к каждому файлу.

Спасибо!

4 ответа

Решение

Нет, волшебной пули нет.

(Кроме того, вы должны понимать, что в S3 нет такого понятия, как "каталог". Есть только объекты с путями. Вы можете получить списки, похожие на каталоги, но символ "/" не волшебен - вы может получать префиксы любым символом, который вам нужен.)

Как кто-то указал, "предварительная архивация" может помочь как в скорости загрузки, так и в скорости добавления. (За счет хранения дубликатов.)

Если загрузка является узким местом, это звучит так, как будто вы скачиваете серийно. S3 может поддерживать тысячи одновременных подключений к одному и тому же объекту, не нарушая пот. Вам нужно будет выполнить тесты, чтобы увидеть, сколько соединений лучше, так как S3 может ограничить слишком много соединений из одного блока. И вам может потребоваться выполнить некоторые настройки TCP при выполнении 1000 соединений в секунду.

"Решение" сильно зависит от ваших шаблонов доступа к данным. Попробуйте перестроить проблему. Если загрузка одного файла происходит нечасто, возможно, имеет смысл сгруппировать их по 100 за раз в S3, а затем разбить их на части по запросу. Если это небольшие файлы, возможно, имеет смысл кэшировать их в файловой системе.

Или может иметь смысл хранить все 5000 файлов в виде одного большого zip-файла на S3 и использовать "умный клиент", который может загружать определенные диапазоны zip-файла для обслуживания отдельных файлов. (S3 поддерживает байтовые диапазоны, насколько я помню.)

Я согласен с ответом @BraveNewCurrency.
Для этого вам понадобится собственный сервер, так как AWS S3 - это просто хранилище значений ключей в реальном смысле.
Инструменты командной строки не будут работать, так как слишком много файлов и аргументов.

Однако у вас есть некоторые варианты, которые могут быть не такими бесплатными или простыми в настройке.

ОПЛАТНЫЕ ВАРИАНТЫ
Я на самом деле связан с дешевым коммерческим проектом, который просто делает это. Они предоставляют как API, так и возможность запуска собственного предварительно сконфигурированного сервера на молнии EC2.
https://s3zipper.com/
https://docs.s3zipper.com/

БЕСПЛАТНЫЕ ВАРИАНТЫ
Вы также можете создавать свои собственные серверы, используя следующие бесплатные пакеты (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())

Вы можете попробовать использовать приложение s3browser в Windows.

Другие вопросы по тегам