データアナリティクス事業本部のueharaです。
今回は、S3間で容量の大きいファイルをBoto3を使ってコピーする際はmultipart_chunksizeに注意しましょうという話をしたいと思います。
はじめに
Boto3を利用してS3間でファイルコピーをするというのはよくあるケースだと思います。
中でも、大きめの容量のファイルをコピーする際は以下のブログでも紹介されているように S3.Client.copy()
メソッドを利用するかと思います。
ただ、この関数をデフォルトのまま使用するとファイルコピーの速度といったパフォーマンス面で課題が生じるケースがあります。
ファイルコピーを行う際の設定値について
S3.Client.copy()メソッドは Config
という引数を持っており、こちらは boto3.s3.transfer.TransferConfigを受け取ります。
ここで、デフォルトのConfigではマルチパート転送における各パートのサイズが 8MB となっており、大きめのファイルのコピーを想定したケースにおいては少々小さめの値となっています。(細かく分割されすぎてしまう)
この値を調整することで、転送速度を向上させることができます。
検証
今回は、バケットA(cm-da-uehara
)に10GBの dummy.dat
を用意し、バケットB(cm-da-uehara-2
)にファイルコピーするケースを考えます。
まずは、以下の通りConfigを設定せずに(デフォルトのまま)コピーを実施してみます。
import time
import boto3
s3_resource = boto3.resource("s3")
copy_target = {
"Bucket": "cm-da-uehara-2",
"Key": "dummy.dat",
"CopySource": {"Bucket": "cm-da-uehara", "Key": "dummy.dat"}
}
start = time.time()
s3_resource.meta.client.copy(**copy_target)
end = time.time()
time_diff = end - start
print(f"{time_diff} sec")
上記を3回計測し、実行時間の平均を算出すると約 40秒 でした。
次に、multipart_chunksizeを 256MB まで上げて検証してみます。
import time
import boto3
s3_resource = boto3.resource("s3")
TransferConfig = boto3.s3.transfer.TransferConfig(
multipart_threshold=256*1024*1024,
multipart_chunksize=256*1024*1024
)
copy_target = {
"Bucket": "cm-da-uehara-2",
"Key": "dummy.dat",
"CopySource": {"Bucket": "cm-da-uehara", "Key": "dummy.dat"},
"Config": TransferConfig
}
start = time.time()
s3_resource.meta.client.copy(**copy_target)
end = time.time()
time_diff = end - start
print(f"{time_diff} sec")
先と同様に3回計測を行い、実行時間の平均を算出すると約 16秒 となりました。
比較すると実行時間が半分以下になっていることが分かります。
更に検証してみる
コピーするファイルは先と同じく10GBとし、multipart_chunksizeと実行時間のグラフを作成してみたところ以下のようになりました。
S3間を繋ぐネットワークの通信品質の状況にも依ると思うので一概には言えませんが、本検証では64MB〜1024MBでは大きな差は感じられませんでした。
マルチパートによる転送は失敗した場合その部分の転送から回復できますが、multipart_chunksizeの値を大きくしすぎてしまうとその分再送にかかる時間も増えるので大きくしすぎるのも注意が必要です。
ユースケースに応じて適切な値を設定頂ければと思います。
最後に
今回は、S3間で容量の大きいファイルをBoto3を使ってコピーする際はmultipart_chunksizeに注意というタイトルで検証を実施してみました。
参考になりましたら幸いです。