S3をEC2インスタンスにマウントして使うときのStorageGateway, s3fs, goofysそれぞれのパフォーマンス
S3をEC2インスタンスにマウントして使うときのStorageGateway, s3fs, goofysそれぞれのパフォーマンス:
オンプレミスで運用している自社システムをAWSに移行する場合に、CSVファイルとしてディスクにためているデータをどうするか。現状は複数あるサーバー間でrsyncを定期的に実行して同期を取っているが、AWS移行後は共通のファイルシステムをマウントして使うことで、同期自体が必要ない運用にしたい。
共通のEFSストレージを複数インスタンスでマウントして共有するという手もあるが、EFSはEBSのようにスナップショットを取ることができない。ということはファイルのバックアップは自前で仕組みを用意する必要がある。しかしできるだけAWSマネージドな仕組みを使うことで運用の手間を減らしたい。
選択肢としては
Storage Gatewayは構築がめんどくさそうなので、とりあえず簡単そうなs3fsとgoofysでやってみて、最後にStorage Gatewayもやってみる。
EC2からS3にアクセスするために、S3FullAccess権限を付与した
マウントポイントを作る。
マウントを実行(
マウントする
ちなみに起動時にマウントするには
インスタンスに Ruby 2.5.1をインストールして以下のようなコードで測定する。
比較対象として、EBS上で実行してみよう。
はやい
当たり前だけどEBSよりはるかに遅い。
EBSよりはるかに遅いのは同じだけど、s3fsより2.5倍ぐらい速い。
ここに書いてある通りに作業してStorage Gatewayを準備する。
http://blog.serverworks.co.jp/tech/2017/03/01/filegateway/
S3バケットを別途作ってNFSとしてマウント
では先ほどのスクリプトを使って試してみる。
おお、これが一番速いようです。ただ、goofysとの差はそこまで大きくはないみたい。
まず最初に、どの方法を使っても速度面でEBSには遠く及びません。したがって多数のファイルを横断的に処理するようなことには全く向いていないと思います。
ただ、性能面で問題ないのであれば、既存のアプリのファイルアクセスをコード変更なしにS3に移行できるという点で魅力的です。
その上で性能面で比較すると一番よさそうなのはStoraga Gatewayみたいです。ただ、これ多分ゲートウェイの機能を提供するインスタンスがSPOFになる気がします。
あと、コスト面でもあまりいいとは言えないと思います。s3fsやgoofysを使う場合はEC2上に直接マウントできるのに対して、ゲートウェイ用にxlarge以上のインスタンスを常時起動しておく必要があるので、その分コストがかかります。
s3fsはこれらの問題がありませんが、StorageGatewayやgoofysに比べるとかなり遅いです。あと、正しくマウントしないと、マウントしても書き込めないなどのちょっとハマりました。
個人的に一番よい印象を受けたのはgoofysです。まずセットアップが一番簡単でした。このあたりはgolangの恩恵かもしれません。依存関係とか気にせず、
そんなわけで、今後はgoofysに的を絞って、もうちょっと詳しく調べてみようと思います。
背景
オンプレミスで運用している自社システムをAWSに移行する場合に、CSVファイルとしてディスクにためているデータをどうするか。現状は複数あるサーバー間でrsyncを定期的に実行して同期を取っているが、AWS移行後は共通のファイルシステムをマウントして使うことで、同期自体が必要ない運用にしたい。共通のEFSストレージを複数インスタンスでマウントして共有するという手もあるが、EFSはEBSのようにスナップショットを取ることができない。ということはファイルのバックアップは自前で仕組みを用意する必要がある。しかしできるだけAWSマネージドな仕組みを使うことで運用の手間を減らしたい。
選択肢
選択肢としては- AWS Storage Gatewayのファイルゲートウェイをセットアップし、NFSを通してEC2にマウントして使用する。
- s3fsでファイルシステムにS3バケットを直接マウント。
- goofysでファイルシステムにS3バケットを直接マウント。
Storage Gatewayは構築がめんどくさそうなので、とりあえず簡単そうなs3fsとgoofysでやってみて、最後にStorage Gatewayもやってみる。
IAMロールの作成
EC2からS3にアクセスするために、S3FullAccess権限を付与した S3FsRole というロールを作成して、テスト用のEC2インスタンスを作る際に作成したロールを指定する。
s3fsのセットアップ
$ sudo apt-get install make automake autoconf git libfuse-dev libfuse2 $ sudo apt-get install libcurl4 libcurl4-openssl-dev $ sudo apt-get install libxml2 libxml2-dev libssl-dev libssl1.1 $ git clone https://github.com/s3fs-fuse/s3fs-fuse.git $ cd s3fs-fuse $ ./autogen.sh $ ./configure $ make $ sudo make install
$ sudo mkdir /usr/local/var/s3fs $ sudo chown ubuntu:ubuntu /usr/local/var/s3fs
/etc/s3fs.conf を編集してマウントしたs3バケットをだれでも使えるようにする。/etc/s3fs.conf
# Allow non-root users to specify the allow_other or allow_root mount options. user_allow_other
uid=1000,gid=1000 はubuntuユーザーのuid,gid)$ sudo /usr/local/bin/s3fs <buckdet名> /usr/local/var/s3fs -o use_path_request_style,rw,allow_other,use_cache=/tmp,uid=1000,gid=1000,iam_role=S3FsRole
goofysのセットアップ
$ sudo apt-get install golang git $ export GOPATH=/usr/local/go $ chown ubuntu:ubuntu $GOPATH $ go get github.com/kahing/goofys $ go install github.com/kahing/goofys
$ sudo mkdir /usr/local/var/s3 $ sudo chown ubuntu:ubuntu /usr/local/var/s3 $ /usr/local/go/bin/goofys --use-content-type <buket名> /usr/local/var/s3
/etc/fstab に/usr/local/go/bin/goofys#<bucket名> /usr/local/var/s3 fuse _netdev,allow_other,--use-content-type,--file-mode=0666,--uid=1000,--gid=1000 0 0
パフォーマンス測定
インスタンスに Ruby 2.5.1をインストールして以下のようなコードで測定する。file_s3_test.rb
time = Time.now
1000.times do |v|
File.open("#{v}", "w") {|f| f.write "hello world #{v}" }
end
1000.times do |v|
File.unlink("#{v}")
end
puts
passed = Time.now - time
puts "#{passed} sec passed."
EBSでの計測
比較対象として、EBS上で実行してみよう。$ mkdir ~/tmp $ cd ~/tmp $ ruby ~/file_s3_test.rb 0.055169964 sec passed.
s3fsでマウントしたS3に対して実行
$ mkdir -f /usr/local/var/s3/ruby_test $ cd /usr/local/var/s3/ruby_test $ ruby ~/file_s3_test.rb 167.091888939 sec passed.
goofysでマウントしたS3に対して実行
$ mkdir -f /usr/local/var/s3/ruby_test $ cd /usr/local/var/s3/ruby_test $ ruby ~/file_s3_test.rb 67.559308286 sec passed.
Storage Gatewayのセットアップ
ここに書いてある通りに作業してStorage Gatewayを準備する。http://blog.serverworks.co.jp/tech/2017/03/01/filegateway/
S3バケットを別途作ってNFSとしてマウント
$ sudo apt-get install nfs-common $ mkdir gatewayfs $ sudo mount -t nfs -o nolock,hard 172.31.53.xxx:/<bucket名> gatewayfs
Storage Gateway + NFSでマウントしたS3に対して実行
では先ほどのスクリプトを使って試してみる。$ cd gatewayfs $ ruby ~/file_s3_test.rb 53.024792688 sec passed.
まとめ
まず最初に、どの方法を使っても速度面でEBSには遠く及びません。したがって多数のファイルを横断的に処理するようなことには全く向いていないと思います。ただ、性能面で問題ないのであれば、既存のアプリのファイルアクセスをコード変更なしにS3に移行できるという点で魅力的です。
その上で性能面で比較すると一番よさそうなのはStoraga Gatewayみたいです。ただ、これ多分ゲートウェイの機能を提供するインスタンスがSPOFになる気がします。
あと、コスト面でもあまりいいとは言えないと思います。s3fsやgoofysを使う場合はEC2上に直接マウントできるのに対して、ゲートウェイ用にxlarge以上のインスタンスを常時起動しておく必要があるので、その分コストがかかります。
s3fsはこれらの問題がありませんが、StorageGatewayやgoofysに比べるとかなり遅いです。あと、正しくマウントしないと、マウントしても書き込めないなどのちょっとハマりました。
個人的に一番よい印象を受けたのはgoofysです。まずセットアップが一番簡単でした。このあたりはgolangの恩恵かもしれません。依存関係とか気にせず、
go get と go install でインストールできました。あとマウントも特にハマるところもなく、すぐにファイルの書き込みや読み込みが行えましたし速度もStorageGatewayには及ばないまでも近い性能が出ています。ネットで色々見ていると不安定だという情報もありましたが、いずれも古い情報だったので現状どうなのかはもう少し試してみないとわからないです。そんなわけで、今後はgoofysに的を絞って、もうちょっと詳しく調べてみようと思います。
コメント
コメントを投稿