TT Lab
はじめる
学ぶ 学習パス コース

オブジェクトストレージとS3

マルチパートアップロードとETagの計算

TT Labで続きを見る

目標

マルチパートアップロードを低水準のAPIで自分で実行し、マルチパートETagを手で計算してサーバーの値と一致させたうえで、中断されたアップロードを整理するところまでを身につけます。

なぜ重要なのか

マルチパートは、SDKが勝手にやってくれることが多く、内部を知らずに通り過ぎやすいものです。しかし、2つの点で必ず知っておく必要があります。1つ目は、ETagです。マルチパートでアップロードされたオブジェクトのETagは、内容のmd5ではなく、各パートのmd5のバイナリ値をつなげてもう一度md5した値で、末尾にパート数が付きます。これを知らないと、「ETagで検証したのに合わない」で何時間も費やします。2つ目は、中断されたアップロードです。完了していないマルチパートのパートは、ストレージ容量を占めますが、オブジェクトの一覧には見えません。クライアントが死んだり、デプロイ中に切れたりしたアップロードが数か月溜まると、請求書に理由のない数百GBが現れます。AWSのコスト漏れの常連で、このラボのステップ7が、その対応です。

ステップ

  1. /root/mp/big.binを、ちょうど25165824バイト(24MiB)で作成してください。内容は再現可能である必要があります(例: 0x00–0xFFの繰り返し)。
  2. /root/mp/parts.txtに、part_size=5242880、parts=5、last_part=4194304の3行を書いてください。5MiBのパート4つに、最後の4MiBのパートが付きます。
  3. /root/mp/mp.pyで、lab-media/big/big.binに対するマルチパートアップロードを開始し、UploadIdを/root/mp/upload_id.txtに保存してください。32文字以上である必要があります。
  4. 5つのパートをアップロードし、各レスポンスのETagを/root/mp/part_etags.txtに<파트번호> <etag>(プレースホルダーはパート番号です)の形式で5行書いてください。
  5. アップロードを完了してください。aws --profile local s3api head-object --bucket lab-media --key big/big.binのContentLengthが25165824で、ETagが-5で終わっている必要があります。
  6. /root/mp/etag_calc.pyでマルチパートETagを手で計算し、/root/mp/etag_calc.txtにcalculated=<값>とserver=<값>の2行(プレースホルダーは値です)を書いてください。2つの値が同じである必要があります。
  7. lab-media/big/orphan.binに対して、アップロードを開始だけして中止してください。/root/mp/abort.outにuploads_before=1 uploads_after=0を書きます。
  8. オブジェクトを/root/mp/downloaded.binにダウンロードし、sha256を元と比較して、/root/mp/verify.txtにsha_match=trueを書いてください。同じファイルに、max_parts=10000、min_part_bytes=5242880の2行も書きます。

参考

大きなファイルを作る

/root/mp/big.binを、ちょうど25165824バイト(24MiB)で作成してください。内容は再現可能である必要があります(例: 0x00–0xFFの繰り返し)。

内容が毎回同じでないと、あとでハッシュを比較できません。固定されたパターンで埋めてください。

パートの分割を計算する

/root/mp/parts.txtに、part_size=5242880、parts=5、last_part=4194304の3行を書いてください。5MiBのパート4つに、最後の4MiBのパートが付きます。

最後のパートを除く各パートには、最小サイズが決まっています。残りが最後のパートです。

マルチパートアップロードを開始する

/root/mp/mp.pyで、lab-media/big/big.binに対するマルチパートアップロードを開始し、UploadIdを/root/mp/upload_id.txtに保存してください。32文字以上である必要があります。

開始すると、識別子を受け取ります。この識別子があって初めて、パートをアップロードできます。

パートをアップロードしてETagを集める

5つのパートをアップロードし、各レスポンスのETagを/root/mp/part_etags.txtに<파트번호> <etag>(プレースホルダーはパート番号です)の形式で5行書いてください。

パート番号は1から始まります。各レスポンスのETagを、順番に集めておかないと、完了できません。

アップロードを完了する

アップロードを完了してください。aws --profile local s3api head-object --bucket lab-media --key big/big.binのContentLengthが25165824で、ETagが-5で終わっている必要があります。

パート番号とETagの一覧を一緒に渡します。完了後、オブジェクトのサイズが元と同じである必要があります。

マルチパートETagを手で再現する

/root/mp/etag_calc.pyでマルチパートETagを手で計算し、/root/mp/etag_calc.txtにcalculated=<값>とserver=<값>の2行(プレースホルダーは値です)を書いてください。2つの値が同じである必要があります。

各パートのmd5のバイナリ値をつなげて、もう一度md5し、パート数を付けます。16進文字列ではなく、バイナリ値です。

開始だけして中止する

lab-media/big/orphan.binに対して、アップロードを開始だけして中止してください。/root/mp/abort.outにuploads_before=1 uploads_after=0を書きます。

中止しないと、パートがストレージ容量を占め続けます。中止後、未完了の一覧が空になっている必要があります。

ダウンロードして完全性を確認し、ルールをまとめる

オブジェクトを/root/mp/downloaded.binにダウンロードし、sha256を元と比較して、/root/mp/verify.txtにsha_match=trueを書いてください。同じファイルに、max_parts=10000、min_part_bytes=5242880の2行も書きます。

sha256で、元と比較します。そして、パートのルール3つを、数字で書いてください。