使用Boto从AWS Glacier下载大型存档

sah*_*ang 6 python boto amazon-web-services amazon-glacier

我正在尝试使用Python包Boto从Glacier下载大型存档(~1 TB).我使用的当前方法如下所示:

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)
Run Code Online (Sandbox Code Playgroud)

问题是作业ID在24小时后到期,这还不足以检索整个存档.我需要将下载分解为至少4个.我该怎么做并将输出写入单个文件?

vol*_*ent 4

看来你可以chunk_size在调用时简单地指定参数,job.download_to_file如下所示:

if job.completed:
    print "Downloading archive"
    job.download_to_file(OUTPUT, chunk_size=1024*1024)
Run Code Online (Sandbox Code Playgroud)

但是,如果您无法在 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
Run Code Online (Sandbox Code Playgroud)

使用此脚本,您应该能够在脚本失败时重新运行该脚本,并继续从您离开的位置下载存档。

第二种方法

通过深入研究 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
Run Code Online (Sandbox Code Playgroud)