X(Twitter) Zenn GitHub RSS 共有

コンテナ環境におけるデータの永続化とコンテナインスタンス間のファイル同期に関して

作成日時: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方式には下記の問題がある。

上記の問題に関しては、以下の解決方法がある。

EFS / FSxを使う

EFSを使用し、それぞれのインスタンスからマウントする。

コンテナ間通信を行う

S3/ DBを使用する場合において、更新が発生した際に他のコンテナへ更新を即時通知する。

Mountpoint for AWS S3を使う

S3でEFSみたいな事が出来るらしい。

(記事作成時点で)この間、アルファリリースされた(2023-03-14)。
サポートされていない機能がまだ多いので今後どうなるか。

構成図

各構成ごとに構成図を書くのは面倒くさかったので、上記の構成を全部ごちゃまぜにした構成図。
見づらいし正しくない。

赤:DB
黄:EFS
青:S3
緑:コンテナ間通信

Amazon ECSサービスディスカバリは参考URLの記事を見て。

構成図