こんにちは、富士通クラウドテクノロジーズ 小林です。
ニフティクラウドには
ニフティクラウドストレージ (旧)
ニフティクラウド オブジェクトストレージ
という2種類のストレージサービスが存在します。
それぞれS3ベースの互換APIであることは変わりませんが、オブジェクトストレージはアップロードの転送量がリージョンに関わらず完全に無料であったり、昨今のデータ増加傾向に合わせたコストメリットが大きい料金設計のサービスになっております。
※ちなみに、両方のサービスともリクエスト量による課金は一切ございません。料金についての詳細はこちらを御覧ください。
この2種類のストレージサービスですが、オブジェクトをそれぞれのサービス間で移行するには少々工夫が必要ですので今回はいくつかやり方をご紹介したいと思います。
方法1. s3fs及びaws cli(syncコマンド)を利用する方法
まず1つ目の方法ですが、s3fsとAWS コマンドラインインターフェイス (以降 AWS CLI) というAWS用のツールを利用します。データの流れは下記のようになります。
クラウドストレージ(旧)→ s3fs → AWS CLI(syncコマンド) → オブジェクトストレージ
導入準備
- AWS CLIのインストールはこちらをご参照ください。
- fuseのインストール
# yum groupinstall "Development Tools"
# wget https://github.com/libfuse/libfuse/releases/download/fuse-2.9.7/fuse-2.9.7.tar.gz
# tar xvfz fuse-2.9.7.tar.gz
# cd fuse-2.9.7
# ./configure --prefix=/usr
# make
# make install
- s3fsのインストール
# wget https://github.com/s3fs-fuse/s3fs-fuse/archive/v1.80.tar.gz
# tar xvfz v1.80.tar.gz
# cd s3fs-fuse-1.80
# ./autogen.sh
# ./configure --prefix=/usr
# make
# make install
# echo "APIアクセスキー:シークレットキー" > ~/.passwd-s3fs
実行例
クラウドストレージ(旧)の バケットsrcbucket
からオブジェクトストレージの バケットdstBucket
に転送する場合
- s3fsマウント
# mkdir /src_dir
# s3fs -f srcbucket /src_dir -o sigv2 -o url=https://ncss.nifty.com
- aws cliでsync実行
# aws s3 sync --endpoint-url https://jp-east-2.os.cloud.nifty.com . s3://dstBucket
方法2. aws-sdkを利用したプログラムで移行
方法1で説明したようなツールを使った方式では、実行に関しての細かな制御ができないため、小さな容量のバケットであれば十分ですが、大規模になるに従って確認方法などに不安が残ります。下記の例はS3互換APIであることを利用して、rubyのaws-sdkを使用したプログラムによる移行を行うことものですが、当然途中でログなどを自由に出力できますので、確認もしやすくなります。
require 'aws-sdk-v1'
require 'nokogiri'
require 'yaml'
# migrate_storate_tool.rb
class MigrateStorageTool
def initialize
src_storage = AWS::S3.new(
:access_key_id => ENV['ACCESS_KEY'] ,
:secret_access_key => ENV['SECRET_KEY'],
:s3_endpoint => ENV['SRC_ENDPOINT']
)
dst_storage = AWS::S3.new(
:access_key_id => ENV['ACCESS_KEY'] ,
:secret_access_key => ENV['SECRET_KEY'],
:s3_endpoint => ENV['DST_ENDPOINT']
)
@src_bucket = src_storage.buckets[ENV['SRC_BUCKET_NAME']]
@dst_bucket = dst_storage.buckets[ENV['DST_BUCKET_NAME']]
end
def migrage
@src_bucket.objects.each do |src_obj|
put_dst_storage src_obj
end
end
private
def put_dst_storage(src_obj)
puts "key: #{src_obj.key} "
data = src_obj.read
dst_obj = @dst_bucket.objects[src_obj.key]
dst_obj.write(data, :multipart_threshold => 100 * 1024 * 1024)
dst_obj.acl = set_src_acl(src_obj)
end
def authenticated_users_acl?(acl)
acl.xpath('//xmlns:URI').to_s.include? "AuthenticatedUsers"
end
def public_read_acl?(acl)
acl.xpath('//xmlns:URI').to_s.include? "AllUsers"
end
def private_acl?(acl)
!public_read_acl?(acl) == !authenticated_users_acl?(acl)
end
def set_src_acl(obj)
src_acl ||= Nokogiri::XML(obj.acl.to_s)
return :public_read if public_read_acl?(src_acl)
return :authenticated_read if authenticated_users_acl?(src_acl)
return :private if private_acl?(src_acl)
src_acl = nil
:private
end
end
ms = MigrateStorageTool.new
ms.migrage
実行方法
- rubyが実行できる環境に上記コードを配置します。
- 環境変数で、下記の値を設定しておきます。
※アクセスキー・シークレットキーはニフティクラウド・コントロールパネルのアカウント管理ページより取得できます。
export ACCESS_KEY=[アクセスキー] #ニフティクラウドAPIのアクセスキー
export SECRET_KEY=[シークレットキー] #ニフティクラウドのシークレットキー
export SRC_ENDPOINT=ncss.nifty.com #移行元のストレージエンドポイント(今回はクラウドストレージ(旧))
export DST_ENDPOINT=jp-east-2.os.cloud.nifty.com #移行先のストレージエンドポイント(今回はオブジェクトストレージ)
export SRC_BUCKET_NAME=bucketname #移行元のバケット名
export DST_BUCKET_NAME=bucketname #移行先のバケット名
- その後rubyスクリプトを実行すると、オブジェクトのコピーを行います。
# ruby migrate_storage_tool.rb
上記プログラムでは、比較的小規模のバケットを想定してるので、エラーハンドリングなど細かい制御など行っておりませんが、データ量などに応じて、通信エラー等発生時のリトライ・一時停止・再開といった処理などを追記すると使い勝手もより向上すると思います。
また今回はaws-sdkのv1を使用したシンプルなサンプルになっていますが、可能であればv2を利用したほうがよりきめ細かいAPI操作を実装できるので移行の際に独自の要件などがある場合はv2を使用した方が良いかもしれません。