📦

s3のマルチパートアップロードawscliコマンドメモ

に公開

概要

マルチパートアップロードは、大容量ファイルを小さなパーツに分割してS3にアップロードする仕組みです。
各パーツは独立してアップロードされ、すべて完了した後にS3がそれらを1つのオブジェクトとして結合します。

制限等は公式に書いてあります
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/qfacts.html

aws s3 cp等は内部的にはマルチパートアップロードを使っているみたいですが、
中断と再開操作が出来ないので手動でやる意味はあります

コマンド

アップロードの流れは以下のような感じです

  1. アップロードの開始: S3に対してマルチパートアップロードを開始するリクエストを送り、アップロードIDを受け取る。
  2. パーツのアップロード: ファイルを分割したパーツを並行してアップロード。各パーツには一意の番号とETag(識別子)が付与される。
  3. アップロードの完了: すべてのパーツのアップロードが終わったら、S3に結合を指示。失敗した場合は中止も可能。

バケットとアップロードするファイルを決める

# 設定
export BUCKET=hoge
export UPLOAD_FILE=huga.tgz

完了してないマルチパートアップロードのリスト表示

aws s3api list-multipart-uploads --bucket $BUCKET

開始

aws s3api create-multipart-upload --bucket $BUCKET --key $UPLOAD_FILE

アップロードIDをメモ

export UPLOAD_ID="abcdef..."

中止する場合は以下のコマンド

aws s3api abort-multipart-upload --bucket $BUCKET --key $UPLOAD_FILE --upload-id $UPLOAD_ID

分割
今回は300MB単位で分割

split -b 300M $UPLOAD_FILE $UPLOAD_FILE-part-
export PART_FILES=($UPLOAD_FILE-part-*)
export PART_COUNT=0

アップロード
これを分割したファイル数分くりかえします

export PART_COUNT=$((PART_COUNT+1))
aws s3api upload-part --bucket $BUCKET --key $UPLOAD_FILE --part-number $PART_COUNT \
    --upload-id $UPLOAD_ID \
    --body ${PART_FILES[$((PART_COUNT-1))]}

各パートをアップロードしたときに表示されるEtagはmd5の値なので次の値と一致するはずです

md5sum ${PART_FILES[$((PART_COUNT-1))]}

進捗表示

aws s3api list-parts --bucket $BUCKET --key $UPLOAD_FILE \
    --upload-id $UPLOAD_ID

parts.jsonファイルを作成 このファイルは処理完了時のチェックに使います
makepart.pyはこんな感じ
parts.jsonはこんな感じのmd5と分割ファイルの番号を書いたファイルです

python makepart.py $UPLOAD_FILE-part-

完了

aws s3api complete-multipart-upload --bucket $BUCKET --key $UPLOAD_FILE \
        --upload-id $UPLOAD_ID \
        --multipart-upload file://parts.json

結合後のEtagが表示されるのでチェックします
最後のEtagはパートファイルのmd5をバイナリで結合した値のmd5値とパート数をつなげた値です
check.pyはこんな感じ

python check.py d9962332854831a96efb57417638f32c-5

Discussion