Загрузка большого архива с AWS Glacier с помощью Boto

Я пытаюсь загрузить большой архив (~ 1 ТБ) из Glacier, используя пакет Python Boto. Текущий метод, который я использую, выглядит следующим образом:

import os
import boto.glacier
import boto
import time

ACCESS_KEY_ID = 'XXXXX'
SECRET_ACCESS_KEY = 'XXXXX'
VAULT_NAME = 'XXXXX'
ARCHIVE_ID = 'XXXXX'
OUTPUT = 'XXXXX'

layer2 = boto.connect_glacier(aws_access_key_id = ACCESS_KEY_ID,
                              aws_secret_access_key = SECRET_ACCESS_KEY)

gv = layer2.get_vault(VAULT_NAME)

job = gv.retrieve_archive(ARCHIVE_ID)
job_id = job.id

while not job.completed:
    time.sleep(10)
    job = gv.get_job(job_id)

if job.completed:
    print "Downloading archive"
    job.download_to_file(OUTPUT)

Проблема в том, что срок действия идентификатора задания истекает через 24 часа, что недостаточно для получения всего архива. Мне нужно будет разбить загрузку как минимум на 4 части. Как я могу это сделать и записать вывод в один файл?


person sahoang    schedule 16.01.2015    source источник
comment
Ваша загрузка занимает больше 24 часов? Я имею в виду, вы ограничены пропускной способностью? В EC2 извлеките/повторно отправьте его на S3, чтобы вы могли загрузить его позже, или перетащите его в ящик EC2 и загрузите оттуда.   -  person tedder42    schedule 17.01.2015


Ответы (2)


Кажется, что вы можете просто указать параметр chunk_size при вызове job.download_to_file вот так:

if job.completed:
    print "Downloading archive"
    job.download_to_file(OUTPUT, chunk_size=1024*1024)

Однако, если вы не можете загрузить все фрагменты в течение 24 часов, я не думаю, что вы можете загрузить только тот, который вы пропустили, используя layer2.

Первый метод

Используя layer1, вы можете просто использовать метод get_job_output и укажите диапазон байтов, который вы хотите загрузить.

Это будет выглядеть так:

file_size = check_file_size(OUTPUT)

if job.completed:
    print "Downloading archive"
    with open(OUTPUT, 'wb') as output_file:
        i = 0
        while True:
            response = gv.get_job_output(VAULT_NAME, job_id, (file_size + 1024 * 1024 * i, file_size + 1024 * 1024 * (i + 1)))
            output_file.write(response)
            if len(response) < 1024 * 1024:
                break
            i += 1

С помощью этого скрипта вы сможете повторно запустить скрипт в случае сбоя и продолжить загрузку архива с того места, где вы его оставили.

Второй метод

Копаясь в коде boto, я нашел «частный» метод в классе Job, который вы также можете использовать: _download_byte_range. С помощью этого метода вы все еще можете использовать layer2.

file_size = check_file_size(OUTPUT)

if job.completed:
    print "Downloading archive"
    with open(OUTPUT, 'wb') as output_file:
        i = 0
        while True:
            response = job._download_byte_range(file_size + 1024 * 1024 * i, file_size + 1024 * 1024 * (i + 1)))
            output_file.write(response)
            if len(response) < 1024 * 1024:
                break
            i += 1
person volent    schedule 16.01.2015
comment
В итоге я использовал метод 2, который хорошо работал с несколькими настройками. Я добавил условное выражение, которое устанавливает для метода записи значение 'ab', если file_size != 0. Таким образом, вывод добавляется, а не перезаписывается при повторном запуске. Кроме того, второй элемент кортежа диапазона байтов отключен на единицу (требуется -1). Наконец, я добавил исключения повторных попыток и проверку хэша, как это показано в исходном коде _download_to_fileob. - person sahoang; 22.01.2015

Вы должны добавить имя_региона в свою функцию boto.connect_glacier следующим образом:

    layer2 = boto.connect_glacier(aws_access_key_id = ACCESS_KEY_ID,
                                aws_secret_access_key = SECRET_ACCESS_KEY,
                                region_name = 'your region name')
person Medo    schedule 23.07.2018