バッチ処理 ECS でやりましょう
以前弁護士ドットコムニュースを聴くという記事を書きましたがその続きです。今後の予定で書いていた読み間違い対策についてはときおりやっています。スマートスピーカー対策はできることは一応全部したけど、なかなか実現できないでいます。それはさておき、気づくと Google / Spotify / Apple それぞれでページができてるのでブラウザでも聴けちゃいそうですね。
弁護士ドットコムニュース音声版は、弁護士ドットコムニュースを Python のプログラムから AWS の Polly を利用して音声化しています。この Python のプログラムは EC2 インスタンス上で動かしていました。当社の方針としてなるべくインスタンスはなくしていきたいと考えていて Elastic Container Service (以降、 ECS) に移設できので、したことを簡単にまとめます。
コンテナ化
幸いプログラム自体の修正は不要で、 Dockerfile を一つ追加するだけで済みました。 Dockerfile の内容は以下のような感じで、ほぼ Python の公式 Docker イメージのページに書かれているままです。
FROM python:3
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD [ "python", "./cli.py", "--prod" ]
ECR にイメージを登録
定期実行する度に pip install が走るのも無駄なので、手元でイメージを作って Elastic Container Registry (以降 ECR)に push しておきます。
Polly の読み間違いを修正するためにたまにコード修正をしているので、先日書いた「Netlify CodeBuild でデプロイや」と同様に CodeCommit / CodeBuild と連携して ECR に push するところまで自動化しておいた方が良いですね。
ECS でタスク定義
なんらかの処理を繰り返し実行するタスクのスケジューリングを設定するためには、タスクを定義しておかねばなりません。
「コンテナメモリの予約用のタスクメモリの最大割り当て」「コンテナへのCPUの最大割り当て」などを適当に設定し、コンテナ定義の中でイメージを指定する項目があります。
ECR にあるイメージを指定するには以下のようなフォーマットになります。
{アカウントID}.dkr.ecr.{リージョン}.amazonaws.com/{イメージのパス}:{タグ}
より具体的にはこんな感じ
xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/myapp:latest
タスクのスケジューリング
どのタイミングで実行するかというのは、固定間隔おきと Cron 式による指定とができます。
固定間隔の場合、値は整数のみ設定可で単位として選べるのは分・時間・日です。 Cron 式の場合はスケジュール表現についてに書かれていますが、普通の Cron と違うところとして年が指定できます。また、ワイルドカードとして使える文字種もちょっと多いので気をつけましょう。
まとめ
何かを繰り返し実行するときは、自由度が高いのでついついバッチサーバーを用意したくなりがちです。そうしてカオスになっているバッチサーバーというのは多くの人が目にしたことがあると思います。また、バッチサーバー自体のメンテナンスが難しくなっているものも数多くあるでしょう。 AWS の中にも定期実行っぽいものが複数あって、どれを使うか迷うところもありますが、 ECS を使うのもなかなか悪くないと思います。