S3へのアップロード速度を上げる方法

以前、S3への転送が遅い件について に書いたように、自宅 Mac mini からS3へのバックアップファイル転送ですが、単純に aws-sdk(Ruby版)を使うより2倍程度になったので書いておきます。


aws-sdk でのアップロードプログラム

次のようなコードで、ローカルにある PATH_TO_FILE ファイルを S3 の BUCKET_NAME にコピー出来ます(もちろん、access_key_idやsecret_access_keyにはあなたのキーを設定して下さい)。

#!/usr/bin/env ruby
require 'rubygems'
require 'aws-sdk'

AWS.config(
  :access_key_id     => 'XXXXXXXXXXXXXXX',
  :secret_access_key => 'YYYYYYYYYYYYYYY',
  :s3_endpoint       => 's3.amazonaws.com'
)
s3 = AWS::S3.new
bucket = s3.buckets['BUCKET_NAME']
path = 'PATH_TO_FILE'
obj = bucket.objects[File.basename(path)]
obj.write(:file => path)

writeメソッドのオプションを指定しよう

AWS::S3::S3Objectのwriteメソッドのドキュメントを見ると、いくつかオプションがあります。ここで転送速度と関係しそうなものには

  • : single_request 転送を一回で行うか、分割して行うか。デフォルトは分割(false)
  • :multipart_threshold 小さいファイルの場合は分割しない、しきい値。デフォルト 16Mbye
  • : multipart_min_part_size 分割する際の大きさ。デフォルト 5Mbye

今回はバックアップなので転送するファイルは 数100Mbye〜数Gbyte です。 デフォルトだと5Mbyeのファイルに分割して送っています。試しに multipart_min_part_size を大きくしたところ、転送時間が多少改善しました。

:single_request => true にして試したところ、デフォルトの半分程度の転送時間になりました!

single_requestで送るとということは一旦ファイルをメモリーに全部取り込んでからS3へ転送されます、したがってメモリーを大量に消費します。バックアップを行っている時に Mac mini は他には何も行っていないので今回は問題ないですが、使用環境によっては multipart_min_part_size を調整する方が良い場合もあると思います。