こんにちは。ハコベルカーゴのサーバサイドの開発を担当している貞元です。 ハコベルカーゴのインフラはAWSで構築されています。 初期のファイル保存先はNFSが採用されていましたが、負荷が高い時に応答が不安定になることがあり、新しくファイルを保存する際はS3が採用され、NFSとS3が混在する結果となりました。 その負債を解消するためにリリースをする際、サービスを止めずにNFSからS3にファイル保存先を移行しました。その時にとった方法を紹介します。
ハコベルカーゴとは
ハコベルカーゴとは荷物を送りたい荷主と、空いた時間に仕事を受注したい運送事業者を直接つなぐマッチングサービスです。 詳しくはこちらを見てみてくださいね。
インフラ・Webアプリケーションの構成
この話で関係するインフラ・Webアプリケーションの構成は以下のとおりです。
インフラ
- AWS
- EC2(Webアプリケーション, NFS)
- S3
アプリ
- Ruby on Rails
- CarrierWave(ファイルアップロード)
問題・改善
上記のようにファイルのアップロード先がNFSとS3が混在しております。 またNFSサーバーはEC2上で動作させていますが、登録ドライバーの増加に伴い負荷が高くなりやすく応答が不安定になることがありアップロードや参照ができないことが発生していました。 そのためNFSを使用するのをやめ、ファイルアップロード先を可用性の高いS3のみに改善することにしました。
ハコベルカーゴは、荷主からは常時注文を受け付けています。 またドライバーも常時運行している状況であるため、サービスを止めないように運用しています。 そのため移行手順は段階的に分け、各手順で問題なく動作していることの確認も含めて約3日おきに実施しました。
移行手順
- 移行前
- ファイルの保存先をNFSとS3の両方に変更
- CarrierWaveのUploaderで保存先をS3に変更gem 'fog-aws'を使用し、storage :fogを指定してS3へアップロード
class ImageUploader < CarrierWave::Uploader::Base storage :fog end
- storeメソッドをオーバーライドして、NFSにも保存
class ImageUploader < CarrierWave::Uploader::Base storage :fog def store!(new_file) super FileUtils.mkdir_p(File.dirname(filepath)) File.binwrite(filepath, file.read) end end
- CarrierWaveのUploaderで保存先をS3に変更gem 'fog-aws'を使用し、storage :fogを指定してS3へアップロード
- 過去のファイルをS3へコピー
- aws cliにて、S3とファイルを同期
aws s3 sync \ --exact-timestamps \ --cache-control="max-age=864000" \ /mnt/nfs/path/to/ s3://path/to/
- この段階でNFSとS3の両方に同じファイルが存在することになる
- aws cliにて、S3とファイルを同期
- ファイル取得先をS3へ変更
- ファイルの保存先をS3のみにし、NFSを停止
まとめ
このように段階的に移行することで、サービスを止めることなく移行することができました。 今回のようなNFSからS3への移行だけでなく、他のケースにも応用できます。バックエンドの大きな変更などがある場合には、このような方法を検討してユーザーへのサービス提供を止めないチャレンジをしてみると良いと思います。
ハコベルおよびラクスルではエンジニアリングの力で世界を変えたいエンジニアを絶賛募集中です! 本記事を読んで興味をもっていただいた方はぜひご連絡いただければと思います!