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?

More than 1 year has passed since last update.

【AWS ECS】データ補完処理をローカル処理からECSに変えたら、「実行時間:16日間→2日間」という爆速で処理が完了した話

Last updated at Posted at 2023-02-21

経緯

今まで、ローカルPCでSAMを起動し、EC2踏み台サーバーを通して、プライベートサブネットのRDSに接続、SQLコマンドをPythonで叩いて、データ補完をしていました。
処理時間は、1日分の処理につき、実行時間が約1時間半かかるデータ補完処理です。

ローカルでDockerを起動するので、EC2インスタンス起動代だけなので、
お金はかかりませんが、「今後もデータ補完するときに課題になるな、、」と感じてました。

AWSのサポート様に問い合わせる

AWSのサポート様に、
「データ補完処理で困ってるんですが、良いサービスはありませんかね・・・?」と聞いてみました。

(AWSサポート様の回答) ECS使うと良いですよー。

なるほど。ECSですか。
良い機会なので、検証も兼ねて試してみることに。

爆速でデータ補完できた

実行環境 ECS(Fargate)
vCPU: 1vCPU
メモリ:3 GB
(従来)
ローカルPCでの実行(SAM)
データ補完にかかる日数 1.7日 16.0日
ローカルPC実行との削減率 89% -
データ補完にかかる料金 374.4円 0円

[内訳]
ECSを1時間稼働させた時の料金: 9.0円
稼働時間: 41.6時間
データ補完にかかる料金: 9.0円 * 41.6時間 = 374.4円

ローカルPC実行(SAM)と、ECSを使った際の比較です。

驚異の89%の削減率!
料金も想定よりずっと安い!
処理時間も大幅に削減できました!

※料金について
AWS公式の料金表と、「ざっくりAWS様」にて算出しました。

大幅に短縮できた要因

処理時間が大幅に短縮できた要因としては、以下が考えられます。
※あくまで考察です。

1. ECSとRDSを同じプライベートサブネットに配置しているから 
(※ローカルPC実行のように、EC2踏み台サーバーを経由する必要がなくなったから)  
2. AWSの処理リソースである、Fargate自体が演算処理のリソースとして優秀だから

今回のAWS構成図

10_ECS_structure.drawio.png

今回は、上記の構成で検証しました。
本記事では、サブネットの作成やRDSの配置・作成などは省略します。
※AWS Secrets Managerは、「シークレット名:postgres」で設定しています。
以下の3点に絞って、記事を投稿します。

1. DockerイメージをECRにPushする
2. ECS関係の設定をする
3. ECSを実行する

今回の記事にて、関係するAWSリソース

- Amazon ECS
- Amazon ECR
- AWS Fargate
- AWS Secrets Manager
- Amazon RDS for PostgreSQL

Amazon ECS

  • AWSでDockerコンテナ実行する際のオーケストレーションサービス。(いわゆる、コンテナを管理するもの)
  • このサービスは管理がメインなので、コンテナ実行は、AWS Fargateで行います。

image.png

Amazon ECR

  • コンテナイメージをリポジトリとして管理するサービス。
  • ECSは、このECRのリポジトリをPullしてきて、実行するようにします。

AWS Fargate

  • サーバーレスで演算実行できるサービス。
  • 従量課金制だが、実行環境のvCPUとメモリの設定を適切に設定(オートスケーリングなど)をすれば、金額は抑えられる。

AWS Secrets Manager

  • データベース認証情報や API キーなどの機密情報を管理できるサービス。

Amazon RDS for PostgreSQL

  • RDS。AWSでPostgreSQLを使えるサービス。

コード・ツリー図

今回は、ECSからRDSへ接続できるかを確認できる、
コードを準備します。

コードは、以下の記事を参考にさせて頂きました。

.
└── repo-ecs/
    ├── main.py
    ├── Dockerfile
    └── requirements.txt
main.py
from time import sleep

import json
import psycopg2
import boto3


try:
    print("RDS: 接続成功")
except Exception as e:
    print("RDS: 接続失敗")


def connect_rds():
    # SecretsManagerからRDSの認証情報を取得
    client = boto3.client(service_name='secretsmanager')
    get_secret_value_response = client.get_secret_value(
        SecretId='postgres')
    secret_info_rds = json.loads(get_secret_value_response['SecretString'])

    # DBの接続設定
    connection_config = {
        'host': secret_info_rds['host'],
        'port': secret_info_rds['port'],
        'database': secret_info_rds['dbname'],
        'user': secret_info_rds['username'],
        'password': secret_info_rds['password'],
        'connect_timeout': 3,
    }

    # 接続
    connection = psycopg2.connect(**connection_config)

    return connection


if __name__ == '__main__':
    # RDSへ接続
    con = connect_rds()
requirements.txt
boto3
psycopg2

Dockerfile

# RUNはイメージをビルドする際に使用するコマンド
# WORKDIRは作業ディレクトリを指定するコマンド
# COPYはイメージにファイルやフォルダを追加するコマンド

# pythonの3.8をベースにする
FROM python:3.8-buster

# 作業ディレクトリを指定
WORKDIR /

# pipのアップグレード
RUN pip install --upgrade pip

# requirements.txtを配置
COPY requirements.txt /

# ライブラリをインストール
RUN pip install -r requirements.txt

# ソースコードの配置・実行
# Pythonはデフォルトで buffer をするようになっているため、"-u"で buffer をしないように設定する。
COPY main.py /
CMD [ "python", "-u", "/main.py" ]

設定手順

1. DockerイメージをECRにPushする

1.1 ECRにアクセスして、「リポジトリを作成」

image.png

1.2 リポジトリ名を入力して、作成

今回は、「repo-ecs」とします。
スクリーンショット 2023-02-20 192810.png

1.3 リポジトリをPushする

作ったリポジトリを選択し、「プッシュコマンドの表示」
image.png

プッシュコマンドが表示されるので、案内通りにコマンドを打ちます。
スクリーンショット 2023-02-20 192812.png

コマンド実行後、ECRを確認すると、イメージがPushされたことが確認できます。

2. ECS関係の設定

次は、ECS関係の設定を行います。

2.1 セキュリティグループを作成する

以下の3つのセキュリティグループを作成します。
EC2の管理画面から、「セキュリティグループ」を選択し、作成します。

1. ECS用のセキュリティグループ(作成名:ecs-sg)
    ※インバウンドルールには、HTTPSのTCPポート番号443を設定してください。
2. RDS用のセキュリティグループ(作成名:rds-sg)
3. SecretsManager用のセキュリティグループ(作成名:sm-sg)

それぞれを作成後、インバウンドルールの編集で以下のようにルールを追加します。

1. ecs-sgに、rds-sgを追加
2. rds-sgに、ecs-sgを追加
3. sm-sgに、ecs-sgとrds-sgを追加

2.2 ECR用のエンドポイントを追加する

今回、Fargateの1.4.0を使うので、ECRのエンドポイントが必要になります。
EC2の管理画面から、「エンドポイント」を選択し、作成します。

1. com.amazonaws.region.ecr.dkr (作成名:ecr-dkr-endpoint)
2. com.amazonaws.region.ecr.api (作成名:ecr-api-endpoint)
3. com.amazonaws.region.s3(ゲートウェイ型)(作成名:ecr-CloudWatchLogs-endpoint)

作成する際には、ECS用のセキュリティグループ(作成名:ecs-sg)を選択してください。

以上で、ECR用のエンドポイントの追加は完了です。

2.3 ECSの設定・タスク定義を行う

ECSのコンソール画面を開き、左側のメニューから「タスク定義」を選択します。
スクリーンショット 2023-02-21 190634.png

「新しいタスク定義の作成」を選択します。
スクリーンショット 2023-02-21 190842.jpg

「タスク定義とコンテナの設定」の設定を行います。

  • タスク定義ファミリー:任意(今回:taskConnectionRDS)
  • コンテナの詳細
    • 名前:任意 (今回:containerConnectionRDS)
    • イメージ URI:ECRのURI名(:latestまで入れましょう)
      ※ECRのURI名は、ECRのリポジトリで確認できます。

スクリーンショット 2023-02-21 191239.jpg

設定後、「次へ」を選択。

「環境、ストレージ、モニタリング、タグの設定」の設定 を行います。

  • アプリケーション環境:Fargate
  • タスクサイズ:任意
    ※スペックによって、料金が変わるので注意。
     私の場合、1vCPU・3GBの初期設定でも十分な性能でした。
  • タスクロール、タスク実行ロール:ecsTaskExecutionRole(このロールは自動で作成されます。)
    スクリーンショット 2023-02-21 192057.jpg

タスク定義が作成されました。
スクリーンショット 2023-02-21 192347.jpg

2.4 ECSの設定・クラスター作成を行う

次は、クラスター作成を行います。

ECSのコンソール画面を開き、左側のメニューから「クラスター」を選択します。
スクリーンショット 2023-02-21 192707.jpg

「クラスターの作成」を選択します。
スクリーンショット 2023-02-21 193003.jpg

「クラスターの作成」の設定

  • クラスター名:任意 (今回:clusterConnectionRDS)
  • ネットワーキング:
    • VPC:任意のVPC
    • サブネット:プライベートサブネットの2つ
      ※パブリックサブネットは選択しない点に注意。
      スクリーンショット 2023-02-21 193329.jpg

上記を設定後、作成を選択します。

image.png

クラスターが作成されました。

2.5 ecsTaskExecutionRoleロールに権限を付与する

IAMにて、ecsTaskExecutionRoleに以下の権限を付与しましょう。

- AmazonRDSFullAccess
- SecretsManagerReadWrite
- AmazonECSTaskExecutionRolePolicy
- EC2InstanceProfileForImageBuilderECRContainerBuilds
- AWSAppRunnerServicePolicyForECRAccess

ECSの設定は以上になります。

3. ECSを実行する

「タスク定義」を選択、作ったタスク定義を選択し、「デプロイ」、「タスクの実行」を選択します。
スクリーンショット 2023-02-21 194231.jpg

「作成」の設定を行います。

  • 既存のクラスター:clusterConnectionRDSを選択
  • ネットワーキング:
    • VPC:任意のVPC
    • サブネット:プライベートサブネットの2つ
      ※パブリックサブネットは選択しない点に注意。
  • セキュリティグループ
    • 既存のセキュリティグループを使用 「ecs-sg」を選択
  • パブリックIP:オン
    スクリーンショット 2023-02-21 194726.jpg

作成を押すと、タスク実行開始。 ECRのコードが実行されます。
image.png

CloudWatchでログを確認すると、RDSに接続できることが確認できました。
image.png

終わりに

以上の設定で、ECSからRDSに接続し、SQLコマンドを使ってSELECTやINSERTなどができるようになります。
処理スピードが早すぎて驚いていました。
設定はあまり難しくはないと思うので、色々試してみると面白いかもしれません。
指摘事項などいただけると幸いです!

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?