4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS S3のオブジェクト(GLACIERも)を丸ごとダウンロードする

4
Last updated at Posted at 2019-06-12

概要

S3バケットに保管されているオブジェクト(STANDARD・GLACIER・GLACIER_IR・DEEP_ARCHIVE)を丸ごとダウンロードするスクリプトです。
S3に保管しているオブジェクトがライフサイクルルールでGLACIERストレージクラスにアーカイブされてしまったので書きました。

対応ストレージクラスは以下のとおりです。

ストレージクラス 内部名 復元の要否 復元時間の目安
S3 Standard など STANDARD 他 不要 即時
S3 Glacier Instant Retrieval GLACIER_IR 不要 即時
S3 Glacier Flexible Retrieval GLACIER 必要 3〜5時間(Standard tier)
S3 Glacier Deep Archive DEEP_ARCHIVE 必要 最大48時間

使い方

サンプルのバケット名と保存ディレクトリ名を書き換え、スクリプトを実行します。

$ python restore_n_download.py

GLACIER(Flexible Retrieval)からの復元には通常3〜5時間、DEEP_ARCHIVEからの復元には最大48時間かかります。スクリプトを一回実行して復元リクエストを送信し、復元完了後にもう一回実行すればダウンロードできます。ダウンロード済みのファイルはスキップされ、復元中のオブジェクトも適切にハンドリングされます。

restore_n_download.py
import boto3
import os
from botocore.exceptions import ClientError

# 設定
CONFIG = {
    'bucket_name': 'awsexamplebucket',
    'filter_prefix': '',
    'base_dir': '/Users/name/awsexamplebucket',
    'restore_days': 1,
    'restore_tier': 'Standard'  # 'Expedited'(1-5分), 'Standard'(3-5時間), 'Bulk'(5-12時間)
}

# 復元が必要なストレージクラス
GLACIER_CLASSES = {'GLACIER', 'DEEP_ARCHIVE'}

def download_object(s3_client, bucket, key, base_dir):
    save_path = os.path.join(base_dir, key)
    if os.path.exists(save_path):
        print(f'Already exists: {key}')
        return
    os.makedirs(os.path.dirname(save_path), exist_ok=True)
    try:
        s3_client.download_file(bucket, key, save_path)
        print(f'Downloaded: {key}')
    except ClientError as e:
        print(f'Error downloading {key}: {e}')

def main():
    s3 = boto3.client('s3')

    paginator = s3.get_paginator('list_objects_v2')
    for page in paginator.paginate(Bucket=CONFIG['bucket_name'], Prefix=CONFIG['filter_prefix']):
        for obj in page.get('Contents', []):
            key = obj['Key']
            try:
                obj_info = s3.head_object(Bucket=CONFIG['bucket_name'], Key=key)
                storage_class = obj_info.get('StorageClass', 'STANDARD')

                if storage_class == 'GLACIER_IR':
                    # Glacier Instant Retrieval: 復元不要、即ダウンロード可
                    download_object(s3, CONFIG['bucket_name'], key, CONFIG['base_dir'])

                elif storage_class in GLACIER_CLASSES:
                    restore_status = obj_info.get('Restore', '')
                    wait_hours = '3〜5時間' if storage_class == 'GLACIER' else '最大48時間'

                    if 'ongoing-request="true"' in restore_status:
                        print(f'Restoration in-progress: {key}')
                    elif 'ongoing-request="false"' in restore_status:
                        download_object(s3, CONFIG['bucket_name'], key, CONFIG['base_dir'])
                    else:
                        print(f'Submitting restoration request ({wait_hours}): {key}')
                        s3.restore_object(
                            Bucket=CONFIG['bucket_name'],
                            Key=key,
                            RestoreRequest={
                                'Days': CONFIG['restore_days'],
                                'GlacierJobParameters': {'Tier': CONFIG['restore_tier']}
                            }
                        )

                else:
                    # STANDARD, STANDARD_IA, ONEZONE_IA など
                    download_object(s3, CONFIG['bucket_name'], key, CONFIG['base_dir'])

            except ClientError as e:
                print(f'Error processing {key}: {e}')

if __name__ == '__main__':
    main()

注意事項

DEEP_ARCHIVEでBulk tierを使う場合

DEEP_ARCHIVEの復元リクエストには GlacierJobParameters(Tier指定)を含めることができますが、Bulk tier を指定した場合はパラメータを省略しなければエラーになります。DEEP_ARCHIVEを対象にする場合はrestore_tierを'Standard'のままにしておくか、ストレージクラスに応じてTierを切り替えるロジックを別途追加してください。

# DEEP_ARCHIVE + Bulk の場合は GlacierJobParameters を渡さない
RestoreRequest={'Days': CONFIG['restore_days']}

参照

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?