0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ECS+EFS+RDS構成はなぜ必要なのか?実務で学んだ役割分担を整理してみた

0
Posted at

はじめに

案件でECS、EFS、RDSを利用した構成を見る機会がありました。

最初は、

EFSにファイルがあるなら、RDSはいらないのでは?
ECSはどうやってRDSの情報を取得しているの?
なぜ環境変数を使うの?

といった疑問を持っていました。

上司に確認しながら整理できた内容が、自分と同じように初学者の方の参考になるかもしれないと思ったのでまとめてみます。

下記はAIに作成させたイメージ図です。
これを詳しく説明していく記事なので、ご参照ください!

image.png

システム構成

全体像は以下のような構成です。

          ECR
           │
(Dockerイメージ取得)
           ↓
      ECS(Fargate)
       ↑        ↑
       │        │
       ↓        ↓
      RDS      EFS

<格納されているデータ>
RDS:メタ情報管理
EFS:実ファイル保存

各サービスの役割は以下のようになっています。

ECR : Dockerイメージの管理
ECS : アプリケーションの実行
RDS: 状態やメタ情報の管理
EFS :  実ファイルの保存(画像などのアプリで使用するデータ)

最初の疑問「EFSだけではダメなのか?」

正直、EFSにファイルが保存されているなら、RDSは必要ないのでは?

と思っていました。

例えば、EFS上に以下のようなファイルが存在していたとします。

/input
 ├── A.csv
 ├── B.csv
 └── C.csv

しかし、この状態ではECS側から見ると、

どのファイルを処理するのか
処理中なのか
処理済みなのか
エラーになったのか

といった情報が分かりません。
ここで次のRDSを挟む理由につながります。

RDSを挟む理由

RDSにはアプリで使用するファイルそのものではなく、管理情報を保存しています。

例えば、以下のようなテーブルを用意します。

id file_name status
1 A.csv WAITING
2 B.csv RUNNING
3 C.csv COMPLETED

ECSは以下のようなSQLで処理対象を取得します。

SELECT *
FROM jobs
WHERE status = 'WAITING';

取得した結果をもとに、

  1. EFS上のファイルを読み込む
  2. 処理を実行する
  3. statusを更新する

という流れになります。

つまり、

EFS = 実データ置き場
RDS = 管理台帳

という役割分担になっています。

全体としては下記のような流れで動作していました。

ECR
↓
Dockerイメージ取得
↓
ECSコンテナ起動
↓
アプリケーションコード実行
↓
RDSへ接続
↓
必要な情報取得
↓
EFS上のファイルを処理

アプリケーションはRDSに接続して情報を取得する

例えばPythonの場合、アプリケーションコード内で下記のように記載されています。

<RDSに接続するためのコード>
conn = psycopg2.connect(
    host=os.getenv("DB_HOST"),
    database=os.getenv("DB_NAME"),
    user=os.getenv("DB_USER"),
    password=os.getenv("DB_PASSWORD")
)

Dockerイメージ内のアプリケーションコードが、
起動後にRDSへ接続して必要なデータを取得している

という形になります。

なぜ環境変数を利用するのか

実務を進めていく際に上司から、

「環境変数を変更するだけで取得するデータを切り替えられるのが便利」

という話を聞きました。

最初はよく理解できませんでしたが、
質問や情報収集を行い理解することができました。

例えば、DEV環境でECSの環境変数が以下のような設定になっているとします。

DB_HOST=dev-db
DB_NAME=dev_db

一方、PROD環境では、

DB_HOST=prod-db
DB_NAME=prod_db

という設定になっているとします。

アプリケーション側のコード内で下記のようにした場合、

host = os.getenv("DB_HOST")
database = os.getenv("DB_NAME")

コードを変更する必要はなくなりますよね。

ということは、同じDockerイメージを利用したまま、

  • DEV用RDS
  • STG用RDS
  • PROD用RDS

を切り替えることができます。

同じDockerイメージを全環境で利用できる

この仕組みにより、

            ECR
             │
    共通のDockerイメージ

    ┌────────┼────────┐
    ↓        ↓        ↓

 DEV環境   STG環境   PROD環境

 DB_HOST   DB_HOST   DB_HOST
    ↓         ↓         ↓
 dev-db    stg-db    prod-db

という構成が実現できます。

環境ごとに別々のDockerイメージを作成する必要がないため、

  • 保守性の向上
  • 運用コストの削減
  • デプロイの簡略化

といったメリットがあります。

まとめ

最初は、

EFSだけで十分では? と思っていました。

しかし実際には、

EFSは実データを保存する
RDSは状態やメタ情報を管理する
ECSは実際に処理を行う

という役割分担になっていました。

また、環境変数を利用することで、

コードを変更せずDockerイメージを作り直さず
接続先や取得するデータを切り替えることができます。

このように責務を分離することで運用性や保守性を高めていることを学びました。

もし同じように、

「EFSだけでよくない?」

と思ったことがある方の参考になれば幸いです。

補足

実際の案件では構成や用途によって設計はさまざまであり、
必ずしもすべてのシステムでEFS+RDS構成が採用されるわけではありません。

今回の記事は、私が携わっている案件で学んだ構成をもとに整理した内容です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?