mcpField
S
s5cmd

s5cmd

公式Agent-ready
github.comクラウド・DevOps4.2ks5cmd72 週間前に更新
リポジトリ公式サイト

s5cmd について

s5cmd は Amazon S3 と連携する高性能なコマンドラインツールです。バッチ操作、並列転送、スクリプト化ワークフローに対応し、ネイティブ AWS ツールより大幅に高速です。

主な機能

  1. 01S3 ファイルを並列アップロード・ダウンロードして転送速度を加速
  2. 02S3 バケット内のオブジェクトをリスト、コピー、削除、同期
  3. 03ワイルドカードとバッチ操作で複数ファイルを処理
  4. 04ローカルファイルシステムとリモート S3 ストレージ間でデータ転送

活用シーン

  1. 01CI/CD パイプラインでのアーティファクト保存と取得を自動化
  2. 02クラウドストレージ全体で大規模なデータ管理
  3. 03コーディングエージェントが S3 リソースに素早くアクセスして操作

インストール

OS またはパッケージマネージャーを選び、コマンドをターミナルで実行します。

$
brew install peak/tap/s5cmd

インストール後にs5cmd --versionを実行して確認します。

コマンド例

よく使うコマンドを使う順に並べています。

01
s5cmd ls s3://bucket/
02
s5cmd cp file.txt s3://bucket/

詳細

Go Report Github Actions Status

README の画像

概要

s5cmd は、S3 とローカルファイルシステムでの実行に対応した非常に高速なツールです。ファイルのタブ補完やワイルドカードに対応するなど、多彩な操作をサポートしています。多数のファイルを扱う際のオブジェクトストレージのワークフローで、大変便利に利用できます。

S3 や同様のオブジェクトストレージサービスを扱うユーティリティはすでにほかにもあるため、s5cmd がほかのツールにはない何を提供するのか、気になるのは自然なことです。

簡潔に言うと、s5cmd は非常に高速です。 s5cmd に関する調査と実験を行った Joshua Robinson に感謝します。彼の Medium の記事から引用します。

アップロードでは、s5cmd は s3cmd より 32 倍、aws-cli より 12 倍高速です。 ダウンロードでは、s5cmd は 40Gbps の回線(約 4.3 GB/s)を飽和させることができます。一方、s3cmd と aws-cli が到達できる速度は、それぞれ 85 MB/s と 375 MB/s にとどまります。

s5cmd のパフォーマンスと高速である理由について詳しく知りたい場合は、ベンチマークのセクションを参照してください。

機能

README の画像

s5cmd は、クラウドストレージサービスとローカルファイルシステムの両方で、幅広いオブジェクト管理タスクに対応しています。

  • バケットとオブジェクトの一覧表示
  • オブジェクトのアップロード、ダウンロード、削除
  • オブジェクトの移動、コピー、名前変更
  • AWS Key Management Service(KMS)を使用したサーバー側暗号化の設定
  • アップロード、コピー、移動時のオブジェクト/ファイルのアクセス制御リスト(ACL)の設定
  • オブジェクトの内容を標準出力に出力
  • SQL 式を使用したオブジェクトからの JSON レコードの選択
  • バケットの作成または削除
  • ストレージクラス別にグループ化したオブジェクトサイズの集計
  • すべての操作でのワイルドカード対応
  • 削除操作での複数の引数への対応
  • 非常に高速にコマンドを一括実行するためのコマンドファイル対応
  • ドライラン対応
  • S3 Transfer Acceleration 対応
  • Google Cloud Storage(およびその他の S3 API 互換サービス)対応
  • コマンド出力の検索に利用できる構造化ログ
  • シェルの自動補完
  • S3 ListObjects API との後方互換性

インストール

公式リリース
バイナリ

リリースページから、Linux、macOS、Windows 用のビルド済みバイナリを入手できます。

Homebrew

macOS 向けに、homebrew のタップが用意されています。

brew install peak/tap/s5cmd
非公式リリース(コミュニティ提供)

Packaging status

警告 これらのリリースはコミュニティによって保守されています。公式リリースと比べて古い場合があります。

MacPorts

macOS では、MacPorts からも s5cmd をインストールできます。

sudo port selfupdate
sudo port install s5cmd
Conda

s5cmd は conda-forge チャンネルに含まれており、Conda からダウンロードできます。

conda-forge チャンネルから s5cmd をインストールするには、次のコマンドで conda-forge をチャンネルに追加します。

conda config --add channels conda-forge
conda config --set channel_priority strict

conda-forge チャンネルを有効にしたら、次のコマンドで conda を使用して s5cmd をインストールできます。

conda install s5cmd

追記:s5cmd feedstock から引用しました。詳しい手順は、README も参照してください。

FreeBSD

FreeBSD では、パッケージとして s5cmd をインストールできます。

pkg install s5cmd

または、ports 経由でインストールできます。

cd /usr/ports/net/s5cmd
make install clean
ソースからビルドする

Go 1.19 以降がインストールされている場合、ソースから s5cmd をビルドできます。

go install github.com/peak/s5cmd/v2@master

⚠️ master からのビルドは安定性が保証されていないことにご注意ください。開発は master ブランチで行われています。

Docker
Hub
$ docker pull peakcom/s5cmd
$ docker run --rm -v ~/.aws:/root/.aws peakcom/s5cmd <S3 operation>

ℹ️ イメージの作業ディレクトリは /aws です。現在の作業ディレクトリをここにマウントすると、システムにインストールした場合と同じように s5cmd を実行できます。

docker run --rm -v $(pwd):/aws -v ~/.aws:/root/.aws peakcom/s5cmd <S3 operation>
ビルド
$ git clone https://github.com/peak/s5cmd && cd s5cmd
$ docker build -t s5cmd .
$ docker run --rm -v ~/.aws:/root/.aws s5cmd <S3 operation>

使い方

s5cmd は、すべての S3 操作で複数階層のワイルドカードをサポートしています。最初のワイルドカードまでのプレフィックスを指定してすべての S3 オブジェクトを一覧表示し、その結果をメモリ上でフィルタリングすることで実現しています。たとえば、次のコマンドの場合、

s5cmd cp 's3://bucket/logs/2020/03/*' .

まず ListObjects リクエストが送信され、その後、一致する各オブジェクトに対してコピー操作が並列に実行されます。

認証情報の指定

s5cmd は、S3 にアクセスするために公式の AWS SDK を使用します。SDK は AWS へのリクエストに署名するための認証情報を必要とします。認証情報はさまざまな方法で指定できます。

  • 名前付きプロファイルを使用するにはコマンドラインオプション --profile を、指定した認証情報ファイルを使用するには --credentials-file フラグを指定します

    # AWS のデフォルト認証情報ファイルにある会社のプロファイルを使用
    s5cmd --profile my-work-profile ls s3://my-company-bucket/
    
    # 自分の認証情報ファイルにある会社のプロファイルを使用
    s5cmd --credentials-file ~/.your-credentials-file --profile my-work-profile ls s3://my-company-bucket/
    
  • 環境変数

    # AWS のアクセスキーとシークレットキーのペアをエクスポート
    export AWS_ACCESS_KEY_ID='<your-access-key-id>'
    export AWS_SECRET_ACCESS_KEY='<your-secret-access-key>'
    export AWS_PROFILE='<your-profile-name>'
    export AWS_REGION='<your-bucket-region>'
    
    s5cmd ls s3://your-bucket/
    
  • s5cmd が Amazon EC2 インスタンス上で実行されている場合は、EC2 IAM ロールを使用します

  • s5cmd が EKS 上で実行されている場合は、Kube IAM ロールを使用します

  • または、--no-sign-request オプションを使って匿名でリクエストを送信できます

    # パブリックバケット内のオブジェクトを一覧表示
    s5cmd --no-sign-request ls s3://public-bucket/
    
リージョンの検出

コマンドの実行中、s5cmd は次の優先順位に従ってリージョンを検出します。

  1. cp コマンドの --source-region または --destination-region フラグ。
  2. AWS_REGION 環境変数。
  3. AWS プロファイルのリージョンセクション。
  4. バケットのリージョンを自動検出(HeadBucket API 呼び出しによる)。
  5. デフォルトリージョンとして us-east-1。
例
バケットが存在するか確認する
s5cmd head s3://bucket/
リモートオブジェクトのメタデータを表示する
s5cmd head s3://bucket/object.gz
単一の S3 オブジェクトをダウンロードする
s5cmd cp s3://bucket/object.gz .
複数の S3 オブジェクトをダウンロードする

次のオブジェクトがあるとします。

s3://bucket/logs/2020/03/18/file1.gz
s3://bucket/logs/2020/03/19/file2.gz
s3://bucket/logs/2020/03/19/originals/file3.gz
s5cmd cp 's3://bucket/logs/2020/03/*' logs/

s5cmd は、指定されたプレフィックスに対して効率的に検索し、指定されたワイルドカードと引数に一致するオブジェクトを見つけます。一致するオブジェクトはすべて並列にダウンロードされます。s5cmd は、保存先ディレクトリがない場合は作成します。

logs/ ディレクトリの内容は次のようになります。

$ tree
.
└── logs
    ├── 18
    │   └── file1.gz
    └── 19
        ├── file2.gz
        └── originals
            └── file3.gz

4 directories, 3 files

ℹ️ s5cmd はデフォルトでソースディレクトリの構造を保持します。ソースディレクトリの構造を平坦化するには、--flatten フラグを使用します。

s5cmd cp --flatten 's3://bucket/logs/2020/03/*' logs/

logs/ ディレクトリの内容は次のようになります。

$ tree
.
└── logs
    ├── file1.gz
    ├── file2.gz
    └── file3.gz

1 directory, 3 files
ファイルを S3 にアップロードする
s5cmd cp object.gz s3://bucket/

ファイルのサーバーサイド暗号化 (aws kms) を設定する場合:

s5cmd cp -sse aws:kms -sse-kms-key-id <your-kms-key-id> object.gz s3://bucket/

オブジェクトのアクセスコントロールリスト (acl) ポリシーを設定する場合:

s5cmd cp -acl bucket-owner-full-control object.gz s3://bucket/
複数のファイルを S3 にアップロードする
s5cmd cp directory/ s3://bucket/

指定したディレクトリ内のすべてのファイルを、ソースのフォルダ階層を維持したまま S3 にアップロードします。

stdin を S3 にストリーム配信する

stdin を s5cmd にパイプすることで、リモートオブジェクトをアップロードできます:

curl https://github.com/peak/s5cmd/ | s5cmd pipe s3://bucket/s5cmd.html

または、アップロード前にデータを圧縮することもできます:

gzip -c file | s5cmd pipe s3://bucket/file.gz
S3 オブジェクトを削除する
s5cmd rm s3://bucket/logs/2020/03/18/file1.gz
複数の S3 オブジェクトを削除する
s5cmd rm 's3://bucket/logs/2020/03/19/*'

一致するすべてのオブジェクトを削除します:

s3://bucket/logs/2020/03/19/file2.gz
s3://bucket/logs/2020/03/19/originals/file3.gz

s5cmd は S3 の一括削除 API を利用します。一致するオブジェクトが 1000 件までであれば、それらは 1 回のリクエストで削除されます。ただし、次のようなコマンドは

s5cmd rm s3://bucket-foo/object s3://bucket-bar/object

s5cmd ではサポートされておらず、エラーになります (2 つの異なるバケットが指定されているため)。これは一括削除リクエストを実行する利点と矛盾するためです。したがって、必要であれば、このケースには s5cmd run モードを使用できます。つまり、

$ s5cmd run
rm s3://bucket-foo/object
rm s3://bucket-bar/object

s5cmd run の詳細と例は、後のセクションで紹介しています。

S3 から S3 へオブジェクトをコピーする

s5cmd はサーバーサイドでのオブジェクトのコピーもサポートしています。

s5cmd cp 's3://bucket/logs/2020/*' s3://bucket/logs/backup/

一致するすべてのオブジェクトを、ソースのフォルダ階層を維持したまま、指定した S3 プレフィックスにコピーします。

⚠️ 5GB を超えるオブジェクトの (S3 から S3 への) コピーはまだサポートされていません。この問題を追跡するためのオープンチケットがあります。

Exclude フィルターと Include フィルターを使用する

s5cmd は --exclude フラグと --include フラグをサポートしており、コマンドで除外または含めるオブジェクトのパターンを指定するために使用できます。

  • --exclude フラグは、操作から除外するオブジェクトを指定します。パターンに一致するオブジェクトはスキップされます。
  • --include フラグは、操作に含めるオブジェクトを指定します。パターンに一致するオブジェクトのみが処理されます。
  • 両方のフラグを使用する場合、--exclude は --include より優先されます。つまり、オブジェクト URL が --exclude パターンのいずれかに一致する場合、--include パターンのいずれかにも一致していても、そのオブジェクトはスキップされます。
  • フラグの順序は結果に影響しません (aws-cli とは異なります)。

次のコマンドは、.log で終わるオブジェクトのみを削除します。

s5cmd rm --include "*.log" 's3://bucket/logs/2020/*'

次のコマンドは、.log または .txt で終わるオブジェクト以外のすべてのオブジェクトを削除します。

s5cmd rm --exclude "*.log" --exclude "*.txt" 's3://bucket/logs/2020/*'

必要であれば、次のように複数のフラグを使用できます。これは request で始まるか .log で終わるオブジェクトをダウンロードします。

s5cmd cp --include "*.log" --include "request*" 's3://bucket/logs/2020/*' .

--include と --exclude を組み合わせて使用することも可能です。次のコマンドは、.log または .txt で終わるオブジェクトのみを同期しますが、access_ で始まるものは除外します。たとえば、request.log と license.txt は含まれ、access_log.txt と readme.md は除外されます。

s5cmd sync --include "*.log" --exclude "access_*" --include "*.txt" 's3://bucket/logs/*' .
SQL を使用して JSON オブジェクトの内容を選択する

s5cmd は SelectObjectContent S3 操作をサポートしており、通常のワイルドカード構文に一致するオブジェクトに対して SQL クエリ を実行し、一致した JSON レコードを stdout 経由で出力します。複数のオブジェクトからのレコードは インターリーブされ、レコードの順序は保証されません(ただし、単一のオブジェクトからのレコードは、 他のレコードとインターリーブされたとしても、順序どおりに到着する可能性が高いです)。

$ s5cmd select --compression GZIP \
  --query "SELECT s.timestamp, s.hostname FROM S3Object s WHERE s.ip_address LIKE '10.%' OR s.application='unprivileged'" \
  s3://bucket-foo/object/2021/*
{"timestamp":"2021-07-08T18:24:06.665Z","hostname":"application.internal"}
{"timestamp":"2021-07-08T18:24:16.095Z","hostname":"api.github.com"}

現時点では、この操作は SQL で選択された JSON レコード のみ をサポートしています。S3 ではこれを lines-type JSON と呼んでいますが、レコードが行で区切られていなくても動作するようです。YMMV.

オブジェクトをカウントし、合計サイズを確認する
$ s5cmd du --humanize 's3://bucket/2020/*'

30.8M bytes in 3 objects: s3://bucket/2020/*
複数のコマンドを並列で実行する

s5cmd の最も強力な機能はコマンドファイルです。数千の S3 および ファイルシステムのコマンドがファイル内で宣言され(または別のプロセスから単純にパイプで渡され)、 複数の並列ワーカーを使用して実行されます。起動されるプログラムは 1 つだけなので、数千の 不要な fork-exec 呼び出しが回避されます。この方法により、S3 の実行時間は毎秒数千操作に 達することができます。

s5cmd run commands.txt

または

cat commands.txt | s5cmd run

commands.txt の内容は次のようになります:

cp 's3://bucket/2020/03/*' logs/2020/03/

# line comments are supported
rm s3://bucket/2020/03/19/file2.gz

# empty lines are OK too like above

# rename an S3 object
mv s3://bucket/2020/03/18/file1.gz s3://bucket/2020/03/18/original/file.gz
Sync

sync コマンドは、S3 バケット、プレフィックス、ディレクトリ、ファイルを S3 バケットとプレフィックス間で同期します。 ソースファイルを source-of-truth として扱い、ソースと宛先の間でファイルを比較します;

  • 宛先に存在しないファイルをコピーします
  • 同期戦略に基づく比較でそれが許可される場合、両方の場所に存在するファイルをコピーします

これは、ソースファイルを変更したり、宛先ファイルを削除したりすることなく(--delete フラグが渡されない限り)、 ソースから宛先への一方向の同期を行います。

次のようなファイルがあるとします;

   -  29 Sep 10:00 .
5000  29 Sep 11:00 ├── favicon.ico
 300  29 Sep 10:00 ├── index.html
  50  29 Sep 10:00 ├── readme.md
  80  29 Sep 11:30 └── styles.css
s5cmd ls s3://bucket/static/
2021/09/29 10:00:01               300 index.html
2021/09/29 11:10:01                10 readme.md
2021/09/29 10:00:01                90 styles.css
2021/09/29 11:10:01                10 test.html

実行すると次のようになります;

  • favicon.ico をコピーします
    • ファイルが宛先に存在しません。
  • styles.css をコピーします
    • ソースファイルがリモートの対応ファイルより新しいです。
  • readme.md をコピーします
    • ソースの方が古いにもかかわらず、サイズが宛先のものと異なります; ソースファイルが source of truth であると仮定します。
s5cmd sync . s3://bucket/static/

cp favicon.ico s3://bucket/static/favicon.ico
cp styles.css s3://bucket/static/styles.css
cp readme.md s3://bucket/static/readme.md

--delete フラグを付けて実行すると、ソースに存在しないファイルが削除されます;

s5cmd sync --delete . s3://bucket/static/

rm s3://bucket/test.html
cp favicon.ico s3://bucket/static/favicon.ico
cp styles.css s3://bucket/static/styles.css
cp readme.md s3://bucket/static/readme.md

ワイルドカードを使用してファイルの一部のみを同期することも可能です。

上記の S3 バケット内の .html ファイルのみを同じローカルファイルシステムに同期するには;

s5cmd sync 's3://bucket/static/*.html' .

cp s3://bucket/prefix/index.html index.html
cp s3://bucket/prefix/test.html test.html

2 つのストレージエンドポイント間の同期は標準ではサポートしていません。現在の解決策は、まずリモートオブジェクトをローカルディスクに同期し、次にローカルファイルをターゲットのリモートストレージに同期することです。たとえば、S3 と Google Cloud Storage を同期したい場合:

s5cmd sync 's3://s3-bucket/path/*' download_folder/

s5cmd --endpoint-url <gcs-endpoint> sync 'download_folder/*' s3://gcs-bucket/path/
Strategy
Default

デフォルトでは、s5cmd はファイルのサイズ および 変更時刻の両方を比較し、ソースファイルを source of truth として扱います。サイズまたは変更時刻のいずれかに差異があると、s5cmd はソースオブジェクトを宛先にコピーします。

mod timesizeshould sync
src > dstsrc != dst✅
src > dstsrc == dst✅
src <= dstsrc != dst✅
src <= dstsrc == dst❌
サイズのみ

--size-only フラグを使用すると、ファイルサイズのみを比較する戦略を使用できます。ソースを信頼できる情報源として扱い、サイズに差がある場合は s5cmd がソースオブジェクトを宛先にコピーします。

更新日時サイズ同期するか
src > dstsrc != dst✅
src > dstsrc = dst❌
src <= dstsrc != dst✅
src <= dstsrc == dst❌
ドライラン

--dry-run フラグを指定すると、実際には操作を実行せずに、実行される操作が出力されます。

s3://bucket/pre/file1.gz
...
s3://bucket/last.txt

次を実行すると

s5cmd --dry-run cp s3://bucket/pre/* s3://another-bucket/

次のように出力されます。

cp s3://bucket/pre/file1.gz s3://another-bucket/file1.gz
...
cp s3://bucket/pre/last.txt s3://anohter-bucket/last.txt

ただし、これらのコピー操作は実行されません。--dry-run を指定せずに実行した場合に s5cmd が行う処理が表示されます。

なお、--dry-run は、副作用のある操作(cp、mv、rm、mb など)であればどの操作にも使用できます。

S3 ListObjects API の後方互換性

--use-list-objects-v1 フラグを指定すると、S3 ListObjectsV1 API が使用されます。このフラグは、ListObjectsV2 API をサポートしていないサービスで役立ちます。

s5cmd --use-list-objects-v1 ls s3://bucket/
シェルの自動補完

bash、pwsh(PowerShell)、zsh でシェル補完がサポートされています。

s5cmd --install-completion を実行すると、使用しているシェルに適した自動補完スクリプトを取得できます。install-completion は自動補完をインストールするのではなく、インストール手順を表示するだけです。名前は後方互換性のために維持されています。

自動補完を有効にするには、次の手順を実行します。

bash および zsh の場合:

自動補完スクリプトを .bashrc および .zshrc ファイルに追加してください。

pwsh の場合:

自動補完スクリプトを s5cmd.ps1 という名前のファイルに保存し、"s5cmd.ps1" ファイルのフルパスをプロファイルファイルに追加してください($profile で場所を確認できます)。

最後に、変更を反映するためにシェルを再起動してください。

Note 自動補完を正しく機能させるには、環境変数 SHELL が正しく設定されている必要があります。つまり、bash では bash バイナリ、zsh では zsh バイナリ、PowerShell では pwsh バイナリを指している必要があります。

Note 自動補完は、次のバージョンのシェルでテストされています。
zsh 5.8.1 (x86_64-apple-darwin21.0)
GNU bash, version 5.1.16(1)-release (x86_64-apple-darwin21.1.0)
PowerShell 7.2.6

Google Cloud Storage のサポート

s5cmd は、GCS、Minio、お好みのオブジェクトストレージなど、S3 API 互換サービスをサポートしています。

s5cmd --endpoint-url https://storage.googleapis.com ls

または、環境変数を使う方法もあります。

S3_ENDPOINT_URL="https://storage.googleapis.com" s5cmd ls

# or

export S3_ENDPOINT_URL="https://storage.googleapis.com"
s5cmd ls

いずれの方法でも、GCS バケットが返されます。

s5cmd は Google Cloud Storage へのアクセスに .aws/credentials を読み込みます。この手順で作成した HMAC キーを使って、.aws/credentials の aws_access_key_id および aws_secret_access_key フィールドに値を設定してください。

s5cmd は、S3、S3 Transfer Acceleration、GCS では仮想ホスト形式のバケット解決を使用します。カスタムエンドポイントが指定されている場合は、パス形式にフォールバックします。

再試行ロジック

s5cmd は、一時的なエラーやサーバー側のスロットリングの可能性があるエラーに対して、指数バックオフによる再試行メカニズムを使用します。invalid credentials や authorization errors など、再試行できないエラーは再試行されません。デフォルトでは、s5cmd は最大 1 分間、10 回再試行します。再試行回数は --retry-count フラグで調整できます。

ℹ️ 再試行可能なエラーを表示するには、デバッグレベルのログを有効にしてください。

整合性の検証

s5cmd は、Content-MD5 ヘッダーと X-Amz-Content-Sha256 ヘッダーを確認して、Amazon S3 にアップロードされたファイルの整合性を検証します。これらのヘッダーは、標準アップロードとマルチパートアップロードの両方で AWS SDK によって追加されます。

  • Content-MD5 は、MD5 アルゴリズムを使用して計算されたファイル内容のチェックサムです。
  • X-Amz-Content-Sha256 は、SHA256 アルゴリズムを使用して計算されたファイル内容のチェックサムです。

これらのヘッダーのチェックサムが実際にアップロードされたファイルのチェックサムと一致しない場合、s5cmd はアップロードに失敗します。これにより、転送中にファイルが破損していないことを確認できます。

S3 が計算したチェックサムが、Content-MD5 ヘッダーと X-Amz-Content-Sha256 ヘッダーで指定されたチェックサムと一致しない場合、S3 はオブジェクトを保存しません。代わりに、MD5 の不一致にはエラーコード InvalidDigest、SHA256 の不一致には XAmzContentSHA256Mismatch を付けて、s5cmd にエラーメッセージを返します。

エラーコード説明
InvalidDigestContent-MD5 ヘッダーで指定されたチェックサムが、S3 によって計算されたチェックサムと一致しません。
XAmzContentSHA256MismatchX-Amz-Content-Sha256 ヘッダーで指定されたチェックサムが、S3 によって計算されたチェックサムと一致しません。

s5cmd がこれらのエラーコードのいずれかを受け取った場合、オブジェクトのアップロードを再試行せず、終了コード 1 で終了します。

MD5 チェックサムが一致しない場合、次のようなエラーが表示されます。

ERROR "cp file.log s3://bucket/file.log": InvalidDigest: The Content-MD5 you specified was invalid. status code: 400, request id: S3TR4P2E0A2K3JMH7, host id: XTeMYKd2KECOHWk5S

SHA256 チェックサムが一致しない場合、次のようなエラーが表示されます。

ERROR "cp file.log s3://bucket/file.log": XAmzContentSHA256Mismatch: The provided 'x-amz-content-sha256' header does not match what was computed. status code: 400, request id: S3TR4P2E0A2K3JMH7, host id: XTeMYKd2KECOHWk5S

aws-cli と s5cmd は、どちらも Amazon S3 を操作するために使用できるコマンドラインツールです。ただし、S3 にアップロードされたデータの整合性を検証する方法には、いくつかの違いがあります。

  • 再試行回数: aws-cli はファイルのアップロードを最大 5 回再試行しますが、s5cmd は再試行しません。
  • チェックサム: ~/.aws/config ファイルで Signature Version 4 を有効にすると、aws-cli はファイルの SHA256 チェックサムのみを確認しますが、s5cmd は MD5 と SHA256 の両方のチェックサムを確認します。

ソース:

ワイルドカードの使用

zsh など一部のシェルでは、* 文字がファイルグロブのワイルドカードとして扱われるため、s5cmd で予期しない結果が生じます。次のような出力が表示されることがあります。

zsh: no matches found

その場合は、次のようにワイルドカード式を単一引用符で囲む必要があります。

s5cmd cp '*.gz' s3://bucket/

出力

s5cmd は構造化出力と非構造化出力の両方をサポートしています。

  • 非構造化出力
$ s5cmd cp s3://bucket/testfile .

cp s3://bucket/testfile testfile
$ s5cmd cp --no-clobber s3://somebucket/file.txt file.txt

ERROR "cp s3://somebucket/file.txt file.txt": object already exists
  • --json フラグを指定した場合:
{
    "operation": "cp",
    "success": true,
    "source": "s3://bucket/testfile",
    "destination": "testfile",
    "object": "[object]"
}
{
    "operation": "cp",
    "job": "cp s3://somebucket/file.txt file.txt",
    "error": "'cp s3://somebucket/file.txt file.txt': object already exists"
}

並行処理の設定

numworkers

numworkers は、グローバルワーカープールのサイズを設定するグローバルオプションです。numworkers のデフォルト値は 256 です。 並列処理を活用できる cp、select、run などのコマンドは、このワーカープールを使用してタスクを実行します。タスクには、アップロード、ダウンロード、または run file 内の任意の処理を指定できます。

たとえば、S3 バケットに 100 個のファイルをアップロードする際に、--numworkers が 10 に設定されている場合、s5cmd は同時にアップロードするファイル数を 10 個に制限します。

s5cmd --numworkers 10 cp '/Users/foo/bar/*' s3://mybucket/foo/bar/
concurrency

concurrency は cp コマンドのオプションです。単一ファイルをアップロードまたはダウンロードする際に、並列処理するパート数を設定します。 このパラメーターは AWS Go SDK で使用されます。concurrency のデフォルト値は 5 です。

numworkers オプションと concurrency オプションは併用できます。

s5cmd --numworkers 10 cp --concurrency 10 '/Users/foo/bar/*' s3://mybucket/foo/bar/

ダウンロードする大きなファイルが少数の場合、--numworkers を非常に大きな値に設定しても、ダウンロード速度には影響しません。この場合、--concurrency をより大きな値に設定すると、ダウンロード速度が向上する可能性があります。

ベンチマーク

以下では、s5cmd のパフォーマンスに関するベンチマークをいくつか紹介します。詳しくは、紹介するベンチマークの出典であるこの記事をご覧ください。

大きなファイル1つのアップロード/ダウンロード

get/putのパフォーマンスグラフ

多数の小さなファイルのアップロード

複数オブジェクトのアップロードパフォーマンスグラフ

異なるハードウェアでのパフォーマンス比較

S3のアップロード速度グラフ

では、この速度はどこから生まれるのでしょうか?

主な理由は2つあります。

  • Go で記述されています。Go は、並行システムの開発を容易にし、マルチコアプロセッサーを最大限に活用できるよう設計された静的コンパイル言語です。
  • 並列化。 s5cmd は並行ワーカープールを起動し、最大スループットの達成を目指しながら、ワークロードを可能な限り並列化します。

パフォーマンス回帰テスト

bench.py スクリプトを使って、異なる2つの s5cmd ビルドのパフォーマンスを比較できます。詳しくは、こちらのREADMEをご覧ください。

高度な使い方

以下に紹介する高度な使用パターンの一部は、次の記事を参考にしています(ありがとうございます! @joshuarobinson)。

s5cmd の操作を Unix コマンドと組み合わせる

S3 にオブジェクトのセットがあり、オブジェクト名の順に並べて一覧表示したいとします。

$ s5cmd ls s3://bucket/reports/ | sort -k 4
2020/08/17 09:34:33              1364 antalya.csv
2020/08/17 09:34:33                 0 batman.csv
2020/08/17 09:34:33             23114 istanbul.csv
2020/08/17 09:34:33             26154 izmir.csv
2020/08/17 09:34:33               112 samsun.csv
2020/08/17 09:34:33             12552 van.csv

より実用的な例として、アボカドの価格のデータセットがあり、必要なバイトだけを取得して、データの数行を確認したいとします。

$ s5cmd cat s3://bucket/avocado.csv.gz | gunzip | xsv slice --len 5 | xsv table
    Date        AveragePrice  Total Volume  4046     4225       4770   Total Bags  Small Bags  Large Bags  XLarge Bags  type          year  region
0   2015-12-27  1.33          64236.62      1036.74  54454.85   48.16  8696.87     8603.62     93.25       0.0          conventional  2015  Albany
1   2015-12-20  1.35          54876.98      674.28   44638.81   58.33  9505.56     9408.07     97.49       0.0          conventional  2015  Albany
2   2015-12-13  0.93          118220.22     794.7    109149.67  130.5  8145.35     8042.21     103.14      0.0          conventional  2015  Albany
3   2015-12-06  1.08          78992.15      1132.0   71976.41   72.58  5811.16     5677.4      133.76      0.0          conventional  2015  Albany
4   2015-11-29  1.28          51039.6       941.48   43838.39   75.78  6183.95     5986.26     197.69      0.0          conventional  2015  Albany

Beast Mode s5cmd

s5cmd では、実行する操作の一覧を含むファイルを、上記の例で示したように run コマンドの引数として渡すことができます。あるいは、コマンドを run: にパイプで渡すこともできます。

BUCKET=s5cmd-test; s5cmd ls "s3://$BUCKET/*test" | grep -v DIR | awk ‘{print $NF}’
| xargs -I {} echo “cp s3://$BUCKET/{} /local/directory/” | s5cmd run

上記のコマンドは 2 回の s5cmd 呼び出しを実行します。まず test というサフィックスを持つファイルを検索し、次に一致する各ファイルに対して ローカルディレクトリへのコピー コマンドを生成し、最後にそれらを run にパイプで渡します。

別の使用例として、30 日より古いファイルをクラウドオブジェクトストレージに移行する場合を見てみましょう。

find /mnt/joshua/nachos/ -type f -mtime +30 | awk '{print "mv "$1" s3://joshuarobinson/backup/"$1}'
| s5cmd run

run コマンドは、すべての操作に対する 万能薬 と考えるべきではないことに言及しておく価値があります。たとえば、次のオブジェクトを削除したいとします。

s3://bucket/prefix/2020/03/object1.gz
s3://bucket/prefix/2020/04/object1.gz
...
s3://bucket/prefix/2020/09/object77.gz

run コマンドで

rm s3://bucket/prefix/2020/03/object1.gz
rm s3://bucket/prefix/2020/04/object1.gz
...
rm s3://bucket/prefix/2020/09/object77.gz

を実行するよりも、単に

rm 's3://bucket/prefix/2020/0*/object*.gz'

を使うほうがよいでしょう。後者は 1000 オブジェクトあたり 1 回の削除リクエストを送信するのに対し、前者のアプローチでは run に渡されたサブコマンドごとに個別の削除リクエストを送信します。したがって、これら 2 つのアプローチの間には、実行時間に大きな差が生じる可能性があります。

免責事項

s5cmd は aws-cli との互換性を目指したり保証したりするものではありません。コマンドやフラグにおける類似点は偶然であり、意図的な互換性として解釈されるべきではありません。

ライセンス

MIT。LICENSE を参照してください。

コメント