コンテナ環境におけるデータの永続化とコンテナインスタンス間のファイル同期に関して
作成日時:2023-04-28
更新日時:2024-08-01
問題点
[自身が稼働している環境(サーバー)上で]ファイルを保存/編集するWEBアプリケーションがあるとする。
このWEBアプリケーションをECSで動かすと、下記の問題が発生する。
- コンテナを削除したらコンテナ内に保存したファイルも消えてしまう。
- 冗長化のためにコンテナインスタンスを複数起動した場合、ファイルを編集したらその編集内容はそのコンテナのみに適用されてしまう。
前者に関しては、Docker Volumeを使用すればタスクが存在する限りデータの永続化が可能だが、
オペミスによる削除の危険性や同期の問題を鑑み、本記事では除外する。
Dockerボリューム - Amazon Elastic Container Service
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/bestpracticesguide/storage-dockervolumes.html
データの永続化とコンテナ間のファイル同期のために、下記の手段を用いる。
S3を使う
S3にファイルの原本を置いて、cronか何かでS3と定期的に同期を行う。
同期にはaws cliの “S3syncコマンド” やs3cmd等を使う。
S3syncは場合によっては遅いのでチューニングを行う。
Amazon S3のsyncコマンドの転送パフォーマンスを改善する | AWS re:Post
数分おきにコンテナ → S3、S3→ コンテナと同期を行う。
RPO(※) = 0が求められているならば、ファイル更新時は即時にS3を更新しに行く。
コンテナ内に置く必要が無く、外部に配信するファイルならば、そのままS3からCDNを経由するなりして配信してもよい。
CloudFrontを経由する場合、キャッシュの関係で即時更新がされないこともあるので、キャッシュのTTLの変更やバージョニング(ファイル名を変える)などで対応する。
※RPO(Recovery Point Objective)
障害発生時、過去の「どの時点まで」のデータを復旧させるかの目標値。
0は障害発生直前。データ損失なし。
DBを使う
DBにファイルの原本をBLOBで突っ込む。
ファイルを更新したら、DBに更新日付等のメタデータとファイル本体を登録する。
cronで定期的に上記テーブルを参照し、変更があればローカルのファイルを更新する。
個人的にBLOBで突っ込むのは好きでない。バックアップ速度とか。
ファイルがバイナリデータならパッと見、内容が分からないとか。
ストレージ料金もS3に比べると高い。
上記2方式の問題点
上記2方式には下記の問題がある。
- 同期がリアルタイムではない。cronの実行間隔による。
- (コンテナ上にファイルを置く必要がある場合)コンテナの初期起動時にS3/ DBから全データを取得しなければならないため、起動が遅くなる。
上記の問題に関しては、以下の解決方法がある。
- EFS / FSx
- コンテナ間通信
- Mountpoint for AWS S3
EFS / FSxを使う
EFSを使用し、それぞれのインスタンスからマウントする。
- 同一のファイルを更新 / 参照するため、リアルタイムである。
- ちょっと料金が高い。
コンテナ間通信を行う
S3/ DBを使用する場合において、更新が発生した際に他のコンテナへ更新を即時通知する。
- ECSのサービスディスカバリーが東京にやってきて、コンテナ間通信の実装が簡単になりました! | DevelopersIO
- Amazon ECSサービスディスカバリ | Amazon Web Servicesブログ
Mountpoint for AWS S3を使う
S3でEFSみたいな事が出来るらしい。
(記事作成時点で)この間、アルファリリースされた(2023-03-14)。
サポートされていない機能がまだ多いので今後どうなるか。
- 高パフォーマンスのオープンソースファイルクライアント、Mountpoint for Amazon S3のご紹介
- GitHub - awslabs/mountpoint-s3: A simple, high-throughput file client for mounting an Amazon S3bucket as a local file system.
- mountpoint-s3/SEMANTICS.md at main · awslabs/mountpoint-S3· GitHub
構成図
各構成ごとに構成図を書くのは面倒くさかったので、上記の構成を全部ごちゃまぜにした構成図。
見づらいし正しくない。
赤:DB
黄:EFS
青:S3
緑:コンテナ間通信
Amazon ECSサービスディスカバリは参考URLの記事を見て。