数百万ファイルや数TB規模のデータをS3バケットとの間で転送した経験がある方なら、AWSのデータ転送にどれほど時間がかかるかをよくご存じでしょう。もし、そのアップロード、ダウンロード、コピーを1〜2桁高速化でき、しかもAWS CLIと同じ感覚で使えるツールがあるとしたら、どうでしょうか。
そこで登場するのが、s5cmdです。

AWS CLIのs3 API呼び出しとs5cmdを的確に表したイメージ
s5cmdは、S3に対するAWS CLIの機能を再現するように設計されたオープンソースのCLIツールです。Pythonベースのインタプリタ言語で実装されたAWS CLIに対し、s5cmdはコンパイル言語であるGoで書かれているため、性能面で大きく優れています。GoベースのSDKは、Go標準の並列処理機能によって多数の高性能なファイル転送を同時並行で実行できるため、個々のファイルだけでなく大量ファイルでも高いスループットを発揮します。これは、Global Interpreter Lockによってマルチコアを効率的に活用できないPythonとは対照的です。
このツールのGitHub上のREADMEでは、AWS CLIに比べてダウンロードが最大12倍高速とされていますが、後述のベンチマーク結果でお見せする通り、条件次第でははるかに高速にデータを転送できます。
転送時間が短くなれば、その分EC2のコンピュート時間、すなわちコストの削減に直結します。これからご覧いただく通り、s5cmdを使わない選択は、相当な金額をみすみす取りこぼしているのと同じです。
さまざまなシナリオでs5cmdとaws s3 cpの性能を比較するため、4TBのデータを対象に以下のタスクの実行時間を測定します。
- EC2からS3へのアップロード
- S3からEC2へのダウンロード
- 同一リージョン内のバケット間コピー
- 異なるリージョン間のバケット間コピー
上記4タスクの実行時間を、4TBの異なる4種類のデータセットについて両ツールで計測します。
- 超大容量ファイル(5GB×819ファイル)
- 大容量ファイル(1GB×4,096ファイル)
- 中容量ファイル(32MB×131,072ファイル)
- 小容量ファイル(256KB×16,777,216ファイル)
さらに、AWS CLIは必ず2回実行します。
- 1回目:AWS CLIをデフォルト設定値のまま実行
- 2回目:高性能EC2インスタンスでスループットを引き出すため、以下の設定値を変更して実行
max_concurrent_requests=64(64コアVMに合わせる。デフォルトは10)
multipart_threshold=1GB(デフォルトは8MB)
multipart_chunksize=256MB(デフォルトは8MB)
アップロード、ダウンロード、コピーの性能は、オブジェクトのサイズや数、並列処理の有無、そしてマルチパートアップロードのファイルサイズしきい値を高めに設定して過剰な並列化を防ぐ工夫など、さまざまな要因と密接に関わります。本ベンチマークではこれらの変数を踏まえ、現実的なユースケースにおけるデータ転送性能を示します。
本記事のベンチマークを再現したい方は、本記事に対応するGitリポジトリをご参照ください。ベンチマークを可能な限り簡単に自動再現できるよう構成しています。
実行時間の比較に入る前に、ひとつだけ補足です。
すべてのベンチマークでは、200Gbpsのネットワークスループットと64基の高性能Gravitonコアを備えた最新世代のc7gn.16xlargeを使用しました。これに、16,000 IOPS・1,000Mbpsスループットの1.1GB gp3 EBSボリューム12本をRAID0構成で接続しています。この構成により、ネットワークスループット、I/Oスループット、処理能力といったリソース側のボトルネックを最小限に抑え、各ツール本来の性能が引き出せるようにしています。
EC2からS3へのアップロード
以下は、同一リージョン内の高性能EC2インスタンスからS3バケットへファイルをアップロードした際のs5cmd cpとaws s3 cpの実行時間です。
なお、以降のチャートはすべてy軸が対数スケールです。

ファイルサイズに関わらず、s5cmdがAWS CLIよりも大幅に高速にアップロードできることがチャートから一目瞭然です。
AWS CLIをデフォルト設定のままにした場合、s5cmdはS3へのアップロードで驚異の19〜26倍高速を記録しました。
AWS CLIの設定値を並列化向きに調整しても、中〜小サイズのファイルを扱うようになるまで効果はわずかです。同時アップロード数を10から64に引き上げると、1,600万個の小ファイルを扱う場合には実行時間の差がある程度縮まりますが、それでもAWS CLIはs5cmdより7.6倍遅いままです。
S3からEC2へのダウンロード
以下は、同一リージョン内のS3バケットから高性能EC2インスタンスへファイルをダウンロードした際のs5cmd cpとaws s3 cpの実行時間です。

EC2からS3へのアップロードと同様、S3からEC2へのダウンロードでもs5cmdはAWS CLIに対して大きく優位ですが、興味深い違いもいくつかあります。
注目すべきは、ファイルサイズが小さい場合を除き、s5cmdのダウンロード性能はアップロード時ほどには伸びないという点です。
AWS CLIをデフォルト設定のままにした場合、s5cmdはダウンロードで15〜17倍高速です。S3アップロード時の19〜26倍と比べるとやや控えめですが、小ファイルのダウンロードではs5cmdの優位性がさらに広がり、30.5倍高速となります。
このようなファイルサイズによる性能差はS3へのアップロードでは見られません。S3からのダウンロードでは、ファイルサイズの小ささが明らかに大きな要因として効いてくるわけです。
AWS CLIの設定値を調整すると、ダウンロードの実行時間はアップロード時よりもはっきり改善され、s5cmdとの差は6.4〜8.7倍まで縮まります。例外は超大容量ファイルで、こちらはダウンロード時間の改善がごくわずかにとどまります。
同一リージョンのS3バケット間コピー
以下は、同一リージョン内の2つのS3バケット間でファイルをコピーした際のs5cmd cpとaws s3 cpの実行時間です。

バケット間コピーになると、コンパイル言語SDKの利点と、CLI設定値チューニングの効果がいよいよ際立ってきます。
AWS CLIをデフォルト設定のままにした場合、s5cmdは同一リージョンのバケット間コピーで27.6〜80.2倍高速です。
ただし、max_concurrent_requestsを10から64に上げるだけでaws s3 cpの性能は大幅に向上し、s5cmdとの差は3.6〜5.0倍まで縮まります。
異なるリージョン間のS3バケットコピー
以下は、異なるリージョン(us-east-1からus-west-2)にある2つのS3バケット間でファイルをコピーした際のs5cmd cpとaws s3 cpの実行時間です。

クロスリージョンのバケットコピーは、s5cmdとaws s3 cpのいずれにおいても、すべてのファイルサイズで同一リージョンのコピーよりはるかに長い時間を要します。それでも、s5cmdのaws s3 cpに対する性能向上倍率は、同一リージョンのコピー時とよく似た傾向を示しているのが興味深い点です。
AWS CLIをデフォルト設定のままにした場合、s5cmdは異なるリージョン間のバケットコピーで27.6〜40倍高速です。max_concurrent_requestsを10から64に上げるとAWS CLIコマンドの実行時間は大きく短縮され、s5cmdとの差は3.5〜4.8倍まで縮まります。
最終結果
以下の折れ線グラフは、aws s3 cpに対するs5cmdの実行時間の性能向上倍率をまとめたものです。

結論:データ転送には常にs5cmdを
ファイルサイズ、転送ファイル数、利用するS3操作の種類を問わず、s5cmdはあらゆるシナリオで優れた性能を発揮します。
s5cmdの性能優位の多くはコンパイル言語で実装されていることに由来しますが、aws s3 cp側にスマートな(あるいは動的に決定される)デフォルト値が用意されていない点も大きく影響しています。AWS CLIの設定値を調整して並列化やアップロードスループットを改善しても、ごく小さなファイルを扱う場合や2バケット間でファイルをコピーする場合を除けば効果はわずかですし、その場合でもs5cmdとの性能差は依然として大きく開いています。よほど特殊な事情がない限り、データ転送にはs5cmdのみを使うことを個人的には強くおすすめします。例えば、組織のセキュリティ規定によりAWS「公式」のツールしかインストールできない、といったケースは例外でしょう。
S3バケットへのデータの出し入れにかかる時間を1〜2桁短縮できれば、組織のデータ利用が拡大するにつれてクラウド請求額の大幅な削減につながります。これを踏まえると、AWSが保守するツールだけで揃えたいという事情を除けば、データ転送でAWS CLIを優先して使うメリットは私の知る限り見当たりません。
本記事の内容を活かし、組織のGCPやAWSデータウェアハウジングを成功に導くにあたって、ご質問はありませんか。
DoiT Internationalまでお気軽にお問い合わせください。シニアエンジニアのみで構成された当社は、高度なクラウドコンサルティング、アーキテクチャ設計、デバッグに関するアドバイスを専門としています。