aws s3 コマンドの並列数を調整してファイルアップロードはどこまで改善できるのか検証してみた

aws s3 コマンドの並列数を調整してファイルアップロードはどこまで改善できるのか検証してみた

Clock Icon2025.07.22

はじめに

先日、s5cmd と AWS CLI の aws s3 コマンドの転送速度を比較検証したところ、AWS CLI の転送速度が予想以上に遅いという結果が出ました。

https://dev.classmethod.jp/articles/s5cmd-vs-aws-s3-cp-speed-comparison/

この結果を受けて、AWS CLI のパラメータを調整することで改善できるか検証しました。具体的には並列度とキューサイズの 2 つのパラメータを変更し、小さなファイルを大量転送するシナリオでの最適化を試みました。

awss3cp.png

検証結果サマリ

  • 最適な並列数:32(今回の検証環境において)
  • キューサイズの影響:なし(1,000 → 10,000 に変更しても性能変化なし)
  • 転送時間: 60 秒から 21 秒へ改善

パフォーマンス改善の結果

並列数 実行時間(キューサイズ 1,000) 実行時間(キューサイズ 10,000) 改善率
10 59.27 秒 60.13 秒 ベースライン
16 37.84 秒 38.76 秒 36% 短縮
32 21.51 秒 22.68 秒 64% 短縮
64 21.10 秒 20.94 秒 65% 短縮
128 20.95 秒 21.06 秒 65% 短縮
256 21.05 秒 21.00 秒 65% 短縮
512 20.95 秒 21.11 秒 65% 短縮

キューサイズ_ 1,000.png

検証環境

構成図

S3 バケットへの転送経路のネットワークを安定させるために、EC2 から VPC エンドポイント経由して S3 バケットアクセスする構成としました。

s5cmd(1).png

EC2 インスタンス

s5cmd コマンドの検証時に用いたインスタンスと同じインスタンスタイプを利用します。

項目 仕様
インスタンスタイプ m8gd.8xlarge
vCPU 32(物理コア数)
メモリ 128 GiB
プロセッサ AWS Graviton4
ネットワーク帯域幅 15 Gbps
Amazon EBS 帯域幅 10 Gbps
インスタンスストレージ あり(NVMe SSD)
OS Ubuntu 24.04 LTS ARM64

アップロード対象のテストファイルについて

小さなサイズのファイルが大量にあるパターンで検証します。インスタンスストアに保存して S3 バケットへアップロードした時間を計測します。

  • 500KB ファイル × 10,000 個(合計約 4.8GB)

事前準備

Graviton(ARM)マシン用の基本的な準備手順を載せておきます。

インスタンスストアのマウント

# インスタンスストアをマウント
sudo mkfs.ext4 /dev/nvme1n1
sudo mkdir -p /scratch
sudo mount /dev/nvme1n1 /scratch
sudo chown ubuntu:ubuntu /scratch
$ df -h /scratch
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme1n1    1.7T  4.8G  1.7T   1% /scratch

AWS CLI インストール

# AWS CLI v2 インストール
curl "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o "awscliv2.zip"
unzip -q awscliv2.zip
sudo ./aws/install
$ aws --version
aws-cli/2.27.50 Python/3.13.4 Linux/6.8.0-1031-aws exe/aarch64.ubuntu.24

テストファイル作成

テストファイルを作成し、インスタンスストアをマウントしたディレクトリ(/scratch)配下に保存しました。

# 小さなファイルを大量に作成(500KB × 10,000個)
for i in $(seq 1 10000); do
    dd if=/dev/zero of=/scratch/small-files/small_file_${i}.dat bs=1K count=500
done

データ転送計測の条件

計測対象

  • ファイル構成:500KB × 10,000 個(合計約 4.8GB)
  • 転送方向:EC2 インスタンス → S3 バケット(VPC エンドポイント経由)

AWS CLI のパラメータ設定

以下 2 つのパラメータを組み合わせて性能を測定します。

並列度(max_concurrent_requests)

同時に実行する転送リクエストの数を指定します。

パターン 並列数 説明
1 10 AWS CLI デフォルト値
2 16
3 32
4 64
5 128
6 256
7 512 s5cmd と同等レベル

キューサイズ(max_queue_size)

転送待ちのリクエストを保持するキューの最大サイズです。

パターン キュー数 説明
A 1,000 AWS CLI デフォルト値
B 10,000 転送ファイル数と同数を指定

計測方法

  • 計測パターン:7 × 2 = 14 パターン
  • 各パターンを 3 回実行し平均値を算出
実行コマンド例
# 並列度とキューサイズを設定
aws configure set default.s3.max_concurrent_requests 16
aws configure set max_queue_size 10000

# 転送時間を計測
for i in {1..3}; do
    echo "=== test${i} ===" >> time_results.txt
    { time -p aws s3 cp /scratch/small-files/ s3://devio-bucket-for-mountpoint/small-files-test${i}/ --recursive --quiet; } 2>> time_results.txt
    echo "" >> time_results.txt
done

検証結果

aws s3 コマンドの並列数を上げることで転送時間を約 3 分の 1 に短縮できました。

キューサイズデフォルト(1,000)

並列数 1回目(秒) 2回目(秒) 3回目(秒) 平均(秒)
10 58.53 59.03 60.25 59.27
16 37.92 37.85 37.76 37.84
32 21.39 21.35 21.79 21.51
64 21.15 21.15 20.99 21.10
128 20.86 20.95 21.03 20.95
256 21.03 21.01 21.12 21.05
512 20.89 20.98 20.99 20.95

キューサイズ_ 1,000.png

キューサイズ10倍に変更(10,000)

並列数 1回目(秒) 2回目(秒) 3回目(秒) 平均(秒)
10 59.9 60.23 60.26 60.13
16 38.82 39.24 38.21 38.76
32 22.27 23.72 22.05 22.68
64 21.08 20.89 20.85 20.94
128 21.14 20.93 21.11 21.06
256 21.05 21.01 20.94 21.00
512 20.93 20.88 21.53 21.11

キューサイズ_ 10,000.png

考察

並列数 32 で性能が頭打ちし、キューサイズは影響しない

検証結果から並列数を 32 以上に増やしても性能向上は見られず、約 21 秒で収束することがわかりました。また、キューサイズを 1,000 から 10,000 に変更しても実行時間への影響はほぼありませんでした。

並列数による性能の頭打ち

並列数を 10 → 16 → 32 と増やす過程では順調に性能が向上しました。32 を超えると実行時間は約 21 秒で収束し、512 まで増やしても改善されません。処理の並列化できない部分や、他の箇所がボトルネックとなっているためでしょう。

キューサイズの変更による影響はほぼなし

タスクキューのサイズを 10 倍に増やしても性能の頭打ちが発生する点は変わりませんでした。キューサイズがボトルネックではなかったことを確認できました。

おわりに

オンプレミスのサーバーや、ワークステーションから S3 に大量にファイルをアップロードすることがあり最近検証していました。実際に利用する環境は SINET6 経由でオンプレミスから AWS 間は 100GB の帯域幅があり、サーバや、ワークステーションなどは 10GB の NIC を積んでいるため通信経路は屈強です。

https://aws.amazon.com/jp/blogs/news/sinet6-aws-ur/

aws s3 コマンドでも並列数を調整することでパフォーマンスを改善できることはわかりました。とはいえ、s5cmd は何も考えなくても相変わらず早かったです。Python 製の AWSCLI と比べると、s5cmd は Golang 製でこれが Concurrency の実力なのでしょうか。並列数は同じ 512 にしても結果は大きく異なり、圧倒的に早い。

$ time -p s5cmd cp "/scratch/small-files/*" s3://devio-bucket-for-mountpoint/small-files-s5cmd-test3/
--- 省略 ---
real 3.14
user 22.78
sys 4.73

参考

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.