[AWS] S3へ巨大なファイルを「マルチパートアップロード」する

  • このエントリーをはてなブックマークに追加
  • LINEで送る

AWS S3へ巨大なファイルをアップロードする際、より高速に転送するには「マルチパートアップロード」を利用することが推奨されています。また一定サイズ以上のファイルはSDKやREST APIからはそもそもPUTすることができません。

マルチパートアップロードというと一見難しそうに聞こえるかもしれませんが理屈も使い方も非常にシンプル。対応したGUIのアプリを使えば裏側で自動的に行なってくれるためそもそも意識する必要すらありません。

今回はAWS CLIとWindowsやmacOS上のGUIのクライアントを利用した方法を取り上げます。

- Sponsored Link -

マルチパートアップロードとは

通常のアップロードは以下のようにファイルをそのままサーバに送りつけるだけです。

マルチパートアップロードではファイルを分割(みじん切りに)し、それぞれのパーツを並行してアップロードします。最終的にすべてのパーツがサーバ上に揃った段階で合体しもとのファイルに復元するという仕組みです。

これにより回線が許す限り並行してファイルの転送が行えるため高速であるだけでなく、一部が転送に失敗しても部分的なやり直しで済むため非常に効率的です。

S3のそもそもの話

オブジェクトのサイズ上限

AWSのドキュメントによると、執筆時点ではアップロード方法によって次のような上限が設定されているようです。

SDK、REST API、CLI
1回のPUTで5Gまで
マネジメントコンソール(Webブラウザ)
160Gまで
マルチパートアップロード API
5Tまで

少なくとも1つのファイルが5Gを超え、マネジメントコンソール以外から巨大なデータを上げる場合はマルチパートアップロードを利用することになります。

Q: Amazon S3 にはどれだけのデータを保存できますか?

格納可能なデータの総量とオブジェクトの数には制限はありません。個別の Amazon S3 オブジェクトのサイズは、最低 0 バイトから最大 5 テラバイトまでさまざまです。1 つの PUT にアップロード可能なオブジェクトの最大サイズは 5 GB です。100 MB 以上のオブジェクトの場合は、マルチパートアップロード機能を使うことをお考えください。
※よくある質問 – Amazon S3より

上記の通りAWS的には100M以上の場合に推奨しているようですね。なおマルチパートAPIはSDK、REST API、CLIからそれぞれ利用することが可能です。

マルチパートアップロードの上限値

1つのオブジェクトの最大サイズは先に述べた通りですが、分割可能な数や、分割した一つ一つのパートの最大サイズも以下のように定められています

項目仕様
最大サイズ5 TB
最大分割数10,000
分割後のサイズ5 MB〜5 GB。最後のパートはサイズ制限なし

料金の罠

ドキュメントを読み進めるとしれっと恐ろしいことが書かれています。

マルチパートアップロードの完了リクエストが正常に送信されなかった場合、Amazon S3 はパートを組み立てず、オブジェクトを作成しません。したがって、パートは Amazon S3 に残るため、Amazon S3 に保存されたパートに対して料金が発生します。
※マルチパートアップロードの概要 – Amazon Simple Storage Service より

つまり何らかの事情で、ファイルのアップロードが中途半端な状態で終了してしまった場合、中途半端なデータが裏側で残り課金され続けるということのようです。なにそれ怖いw

不完全なデータを確認&削除

Webブラウザからマネジメントコンソールを覗いても表示されないため、CLIなどから直接S3のAPIを叩きます。

$ aws s3api list-multipart-uploads --bucket (バケット名)

残骸が表示された場合にはCLIから以下のコマンドで削除することができます。

$ aws s3api abort-multipart-upload --bucket (バケット名) --key (ファイル名) --upload-id (アップロードID)

ライフサイクルを設定する

不完全なデータをCLIから毎回削除するのは流石に現実的ではないので、ライフサイクルの設定を行い常にお掃除がされるようにします。というわけでアップロードが途中で失敗しても一定時間が経過したら自動的に不完全なファイル(オブジェクト)が削除されるようライフサイクルを設定していきます。

マネジメントコンソールからS3のバケットを開き「管理」メニュー内にある「ライフサイクルルールを作成する」ボタンをクリック。

ページ下の方にある「期限切れの削除マーカーまたは不完全なマルチパートアップロードを削除する」にチェックすると新しい入力項目が登場しますので「不完全なマルチパートアップロードを削除」にチェックし、適当な日数を入力すれば完了です。

CLIからライフサイクルの設定を行う場合は以下のページを参照ください。

アップロード方法

AWS CLI

cpを利用するだけで、巨大なファイルを指定した場合は自動的にマルチパートアップロードが裏側で行われます。

$ aws s3 cp filename.mp4 s3://bucketname/

設定値はコマンドで変更可能です。

# スレッドの個数
$ aws configure set default.s3.max_concurrent_requests 10

# マルチパートアップロードを採用するファイルサイズの閾値
$ aws configure set default.s3.multipart_threshold 64MB

# チャンクサイズ
$ aws configure set default.s3.multipart_chunksize 16MB

# 最大帯域幅
$ aws configure set default.s3.max_bandwidth 50MB/s

アプリ

Cyberduck

macOSでお馴染みのCyberduckがマルチパートアップロードに対応しています。Windows版もあり基本無料で利用可能です。MacAppStoreでも入手できますがこちらは有料。開発を支援したい方はぜひ協力してあげてください。

S3 Browser

Windows用のS3クライアントであるS3 Browserがマルチパートアップロードに対応しています。

5Mを超えるファイルは自動的にマルチパートアップロードになるようですが、無料版ではスレッド数が2つまでに制限されます。より高速に転送したい、またはお仕事で利用する場合にはPro版を購入する必要があります(執筆時点で1ライセンス$29.99)

WinSCP

Windowsでのファイル転送ソフトとして有名なWinSCPでS3へアップロードすることは可能ですが、マルチパートアップロードには非対応のようです。

フォーラムを覗いてみると2020年6月時点の書き込みで、多くの声が集まれば実装するかも…との作者の方の発言があります。

(質問)
Could you guys please improve the S3 interface to use multipart uploads?

(回答)
Thanks for your suggestion.
We will see, if more people ask for this.
※WinSCPフォーラムより

本当にスピードアップするの?

計測方法

AWS CLIを利用して実験します。今回利用するバージョンは以下になります。

$ aws --version                                      
aws-cli/2.1.7 Python/3.9.0 Darwin/19.6.0 source/x86_64 prompt/off

アップロードするファイルはddコマンドで100Mと1Gbyteのファイルを用意しました。

$ dd bs=100m count=1 if=/dev/urandom of=file1
$ dd bs=1g count=1 if=/dev/urandom of=file2

時間の計測にはtimeコマンドを利用します。

$ time aws s3 cp file1 s3://example.com/ 

通常のアップロードへの切り替えは単純にmultipart_thresholdのサイズを大きく設定した状態で行いました。

$ aws configure set default.s3.multipart_threshold 10GB

計測中はネットワークを利用しないようルンバが掃除してくれるのを眺めながら待ちます。あとテトリスミニに最近ハマってるのですがこちらも完全オフラインなのでおすすめw

計測結果

100M byte

単位は秒です。なるほど、これは誤差だw

回数通常マルチパート
118.54319.490
212.57221.362
321.74417.342
423.29416.962
516.58915.538
平均18.548418.1388

1G Byte

こちらはマルチパートアップロードがおよそ25%ほど高速にアップロード出来ていますね。やはりファイルサイズが大きくならないと明確な差は生まれないようです。

回数通常マルチパート
1140.09106.44
2147.30105.10
3171.38111.97
4135.47115.63
5144.93107.41
平均147.834109.31

このあとmax_concurrent_requestsなども調整してみましたが今回は明確な差は見られませんでした。

参考サイト

コメント

感想やご質問などお気軽にどうぞ。広告が表示されている場合は下にスクロールしてください。投稿にはSNSへのログインが必要です。

このブログを応援する

お寄せいただいたお気持ちは全額サーバ代や次の記事を執筆するための原資として活用させていただいております。この記事が参考になった場合などぜひご検討ください。

PayPal(ペイパル)
PayPalで300円支払う
※金額は任意で変更できます。
※100円でも泣いて喜びますw
※住所の入力欄が現れた場合は「no needed」を選択ください
これまでのご協力者さま
- Sponsored Link -