GCS → S3 へのデータコピーは、gsutil 単体でよりも gsutil + AWS CLI の方が早い
他の人がやっている様子を見たところ、 gsutil と AWS CLIをパイプで繋いでもできる様子。
また、gsutil はファイルサイズの上限があるようなので、それを超える場合もパイプでやると良いようだった。
試してみたところ、性能的にも gsutil + AWS CLIの方が早い様子があったので検証してみる。
インスタンスはEC2 の c5.large インスタンスを利用。GCS/S3バケットもEC2インスタンスも東京リージョン。
検証スクリプト
# 環境変数設定 GCS_PATH="gs://my-bucket/" S3_PATH="s3://my-bucket/gsutil-speed/" # 実行パラメータとして、ファイルサイズ(KB)を設定 kbs=(1 1000 5000 10000 50000 100000 500000 1000000) # time コマンドで計測するための出力 TIMEFORMAT="%3R,%3U,%3S" # 出力先CSVのヘッダ行 echo "kb,tool,real,user,sys" > results.csv # ファイルサイズごとにループ for kb in ${kbs[@]} ; do echo $kb # ファイル作成 dd if=/dev/urandom of=${kb}.dat bs=1024 count=${kb} # コピー元となる GCS バケットに置く gsutil cp ${kb}.dat ${GCS_PATH} # gsutil 単体での転送を、3回計測 for i in `seq 3`; do exec 3>&1 4>&2 result=$( { time gsutil cp ${GCS_PATH}${kb}.dat ${S3_PATH}{kb}.dat 1>&3 2>&4; } 2>&1) exec 3>&- 4>&- echo "${kb},gsutil,${result}" >> results.csv done # gsutil + AWS CLI での転送を、3回計測 for i in `seq 3`; do exec 3>&1 4>&2 result=$( { time gsutil cp ${GCS_PATH}${kb}.dat - | aws s3 cp - ${S3_PATH}{kb}.dat 1>&3 2>&4; } 2>&1) exec 3>&- 4>&- echo "${kb},gsutil+cli,${result}" >> results.csv done done
結果
データ量 | gsutil 実行時間(秒) | gsutil+AWS CLI 実行時間(秒) |
---|---|---|
1KB | 1.37 | 1.36 |
1MB | 1.66 | 1.46 |
5MB | 2.18 | 1.56 |
10MB | 2.75 | 1.75 |
50MB | 7.45 | 2 |
100MB | 13.41 | 2.6 |
500MB | 67.98 | 5.52 |
1GB | 123.01 | 8.66 |
考察
随分差がある。データ量が大きければ大きいほど乖離が大きい。
- gsutil の場合は実行時間がデータ量に比例しているので、並列化が効いていないように見える。
なお、gsutil 単体 +
-m
オプションでやってみると、コケる。
[Errno 32] Broken pipeB/ 97.7 MiB] 0% Done CommandException: 1 file/object could not be transferred.
- gsutil + AWS CLI だと比例していないので、適度に並列化が効いているんだろうと思われる。
-m
オプションなしでも有効。実際にAWSでCreateMultiUpload API を叩いている。
余談
time コマンドの結果をbashの変数で受け取るのに手間取った。以下のstackoverflowから流用。