AWSを利用したサーバーレスなメールバッチの設計

AWSを利用したサーバーレスなメールバッチの設計

こんにちは!
アイスタイルAdvent Calender2021の12/5担当、新卒2年目Webエンジニアのakibarです🐑
現在は基盤開発グループに所属し、主に決済基盤システムの運用・開発に携わっています。

去年のアドカレも12/5担当だったみたいですが…狙ったわけではないです😳

今回は「AWSを利用したサーバーレスなメールバッチの設計」について執筆させていただきます。

目次

  • 概要
  • メール配信機能の要件
  • メールバッチの構成
  • 設計ポイント
    • 配信メール種別が増えた場合の拡張性
    • DynamoDB Streamsの利用
    • 運用・保守性
  • 苦労した点
    • AWSサービスの種類が多すぎる
    • DynamoDBのテーブル設計
  • まとめ

概要

新卒研修後に配属になった部署にて、美容エディターと化粧品ブランドPR担当をつなぐプラットフォーム「ビューティプレスボード」の開発に携わっておりました。
今年の初めに追加となったメール配信機能の設計・実装を担当させていただきましたので、
そのときの設計について記事にさせていただきます📰
メール配信機能の要件から実際に設計したアーキテクチャ構成、
設計ポイントと苦労した点について綴ります!

ビューティプレスボードのサービス詳細については下記をご参考ください💄

▼ @cosme for BUSINESS『ビューティプレスボード』
https://business.cosme.net/service/beautypressboard

メール配信機能の要件

今回設計を担当した機能は、ビューティプレスボードを利用してくださっているブランド担当者様・プレス様向けに通知メールを配信する機能です。

該当機能の要件の一例は下記でした。

メール種別① メール種別②
配信時間 日次 10:00 毎時 00分00秒
失敗分リカバリ時間 日次 16:00 日次 10:00
通数 MAX 50,000通 / 月 MAX 210,000通 / 月

メールバッチの構成

当初はバッチサーバーを新しく構築して新サーバー内でcronでバッチ起動など検討していましたが、
弊社内でもクラウド化を推進しているためクラウド上でサーバーレスな設計に挑戦してみることになりました。

結果 Lambda / DynamoDB / EventBridge / CloudWatch などを利用したサーバーレスな構成となりました。
メール配信の機能自体は外部のメール配信サービスを利用しています。

メールバッチ構成図
▼ 処理の流れ

①EventBridgeで配信対象取得Lambdaを定時起動
 ⇒オンプレDBのデータをもとにDynamoDBに配信情報を追加

②レコード変更イベントがDynamoDB Streamsに流れる

③DynamoDB Streamsをトリガーにメール配信Lambdaが起動
 ⇒外部メール配信サービスのAPIにてメール配信
 ⇒配信結果をDynamoDBのステータスに反映

④EventBridgeで失敗分再送Lambdaを定時起動
 ⇒DynamoDBのステータスを変更
 ⇒以降②③によりメールが配信される

処理の詳細については今回は割愛いたします!

設計ポイント

今回設計したアーキテクチャ構成のポイントについて3点紹介いたします💡!

配信メール種別が増えた場合の拡張性

配信対象取得Lambda/失敗分再送Lambdaをメールの種別ごとにLambdaを作成することで、
メール配信Lambdaは共通で利用できる構成になっています。

今後配信メール種別が増えた場合もLambda追加で対応が可能です。

DynamoDB Streamsの利用

できるだけAWSの各サービスで実装されている機能で連携ができる構成にしたいと考えていたため、
メール配信LambdaのトリガーにはDynamoDB Streamsを採用いたしました。

DynamoDBのレコード変更イベントをLambdaのトリガーに設定できるため、
各Lambda間で別Lambdaの起動など実施しなくても、DynamoDBへINSERT/UPDATEすることでLambdaを起動させることができます。

▼ AWSデベロッパーガイド『DynamoDB StreamsとAWS Lambdaのトリガー』
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Streams.Lambda.html

運用・保守性

フルマネージドなサービスのみ利用しているため、バッチ用サーバーなどの運用コストがかかりません。
サーバーのCPU使用率やログファイルによる容量逼迫なども気にしなくて大丈夫です。

※ログファイルの保管にかかる料金などは別途検討が必要です※

苦労した点

初めてのアーキテクチャ設計がAWSを利用した構成だったため、
色々と大変なポイントがありその都度周りの方々に助けていただきました🙏

ご相談に乗っていただいた方々ありがとうございました!

AWSサービスの種類が多すぎる

皆さんご存知かと思いますが、AWSのサービスは豊富な種類を誇っています。

現在、AWS では 200 を超えるサービスを提供しており、2020 年には 2,757 回のリリースを実施しました。
『AWSのクラウドが選ばれる10の理由』AWS

200を超えるサービスがあるということは、つまりサービスの組み合わせも無限大というわけです…。
配信管理テーブルからメール配信の処理の流れについては SQS などのキューイングサービスを利用しようかと考えていたり、
どのサービスをどう組み合わせるのが要件に適しているか検討するのが大変でした。

弊社インフラエンジニアのkamiyamkさん、sugimotorさんには設計の相談から構築までお世話になりました🙏

DynamoDBのテーブル設計

DynamoDBのテーブル設計以前にNoSQLのテーブル設計をするのが初めてだったのでとても苦労しました。
パーティションキー・ソートキーをどのカラムにすると効果的に分散できるか、
グローバルセカンダリインデックス(GSI)をどのように設定すると効率的にクエリを実行できるかの検討が特に悩みました。

弊社DBAのsuzukitoさんには大変お世話になりました!

▼ AWS『Amazon DynamoDBのコアコンポーネント』
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey
▼AWS『DynamoDB のグローバルセカンダリインデックスの使用』
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GSI.html

まとめ

AWSに関する知識も豊富とは言えない状態だったと思いますが、
じっくり新機能のアーキテクチャ設計に挑戦する機会をいただけてとても良い経験になりました。

DynamoDBとLambdaの連携など、AWSのサービス間連携のしやすさを実感できる設計になったと思います。
こちらの記事が何かのご参考になれば幸いです。

弊社のアドベントカレンダーもまだまだ始まったばかりなので、この後の記事もお楽しみに!
最後までご覧いただきありがとうございました🐇

20新卒入社・基盤開発グループ所属