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.