分間10万リクエストを捌く、メール/プッシュ通知 大量配信AWSアーキテクチャ
こんにちは。
株式会社ココナラで技術戦略室を担当しているKと申します。
本記事では、ココナラで使用しているメール/プッシュ通知の配信基盤についてお話ししたいと思います。
この基盤は2年ほど前に構築したものです。
今回記事に取り上げたのは、今後AWSにコストを抑えた上で高速に処理する仕組みを構築する際の参考になるかもしれないと思ったためです。
本記事では、大きく以下の2点をお話しします。
- 構築に至った背景
- アーキテクチャの詳細と結果
前提として、ECサイトと配信の関係
一般的に、ECサイトではマーケティングを目的として、メールやプッシュ通知を配信します。
ユーザーが多ければ多いほど、その配信数も多くなります。
ココナラもスキルのECサイトの構造であり、ユーザー数は300万人を超えています(2022年8月末現在)。
したがって、他のECサイトと同様に多数のメールやプッシュ通知を配信しています。
配信基盤を構築した背景
時系列に沿って、お話しします。
昔
もともとはこのような配信に外部のサービスを利用していました。
ユーザー数や配信数が少なかった頃はそれでも問題はありませんでした。
少し前
ココナラのプロダクトの成長にともなって、外部のサービスを使うのが難しくなってきました。
具体的には、次の2つの問題が生じました。
-
コストが見合わなくなってきました。
- 外部サービスはユーザー数や配信数に応じて課金されることが多いです。
そのため、ココナラのユーザー数の増加に耐えられなくなりました。
- 外部サービスはユーザー数や配信数に応じて課金されることが多いです。
-
使いづらさが目立ってきました。
- 当然ですが、外部サービスはココナラ向けには最適化されていません。
そのため、配信の設定作業に時間がかかっていました。 - ヒューマンエラーが発生しやすいという問題もありました。
- 当然ですが、外部サービスはココナラ向けには最適化されていません。
その後
これらの問題を解決するため、配信基盤をゼロから構築することにしました。
配信基盤に求められるもの
自分たちで配信基盤を構築するにあたり、大きく次の3点を考慮する必要がありました。
1. 配信スピード
ユーザーに効果的に訴求するには、それに適した時間に配信する必要があります。
例えば、ある配信において、19時に配信するとCTR(クリック率)が最も高くなるとします。
この仮定のもとに19時から配信を開始し、すべての配信が完了したのが22時だとします。
この場合、ほとんどの配信は最適な時間を逃してしまったことになります。
もともと使用していた外部サービスの配信スピードは、分間6,000件でした。
最低限、このスピードを維持する必要がありました。
2. スケーラビリティ
ユーザー数の増加に耐えられるようにスケールできる必要があります。
現在、ココナラのユーザー数はどんどん増えています。
ユーザー数の増加にともなって、配信時間が延びていくようでは将来使えなくなってしまいます。
したがって、スケーラビリティは重要な要素です。
3. コスト(費用)
コストを最大限抑えられるような設計にする必要があります。
以前よりもコストがかかってしまうようでは、そもそも移行の目的が果たせなくなってしまいます。
構築した配信基盤のアーキテクチャ
以上の要素を満たせるように設計したアーキテクチャがこちらです。
ココナラでは、現在この仕組みを使用して大量配信を行っています。
実際にはもっと複雑なのですが、ここでは簡略化して記載しています。
配信基盤の設計で考慮したこと
配信基盤に求められる各要素を満たせるように、それぞれ以下のように設計しました。
1. 配信スピード
以下の方針で設計しました。
並行処理
- 並行処理に強いGo言語を採用する
- 実行回数が多い(ボトルネックになりうる)処理は並行処理にする
- 並行処理の排他制御として、DynamoDBを利用する
- ビッグデータを使用したターゲティングは、クエリ性能に優れたBigQueryで行う
配信スピードの評価
構築後に性能テストで測定したところ、1分間で100,000件配信できる性能になりました。
これは、もともと利用していた外部サービスの16.7倍のスピードです。
実際には、配信ワーカーのLambdaの数を増やすことでさらに速くすることもできます。
しかし、配信タイミングがあまりにも集中すると、サイトのキャパシティ以上にアクセスが集中してしまうという問題があります。
そのため、現在は配信ワーカーの数を抑えて運用しています。
2. スケーラビリティ
以下の方針で設計しました。
分散処理
- 一番時間のかかる処理をスケールできるようにする。
- 一番時間がかかるのは、外部ネットワークとの通信をともない、かつ、実行回数も多い配信APIを叩く部分。
- この部分を複数の配信ワーカー(Lambda)で分散処理する。
- 配信ワーカーの数を増やせば増やすほど、一定時間に捌ける量が増える設計にする。
スケーラビリティの評価
設計意図通りの結果になりました。
性能テストにおいて、配信ワーカーの数を増やせば増やすほど、ほぼ比例して捌ける量が増えていくことが確認できました。
例えば、10から20に増やすと一定時間に捌ける量がリニアに2倍 になりました。
どれだけ増やしても性能限界が見えなかったので、限界を確認する前に性能テストはやめてしまいました。
3. コスト(費用)
以下の方針で設計しました。
サーバーレスアーキテクチャ
- EC2、RDSなどの起動しておくだけで課金されるサービスは使用しない
- 配信処理が動いている間だけ課金されるサーバーレス系のサービスのみで構成する
- 使用したAWSのサービス
- API Gateway
- Lambda
- EventBridge (Lambdaで動的に作成)
- ECS Fargate (スケジュールタスク)
- DynamoDB (オンデマンドキャパシティーモード)
- 使用したAWSのサービス
コストの評価
実際の金額は控えますが、この方針で設計した結果、もとの外部サービスと比較して1/20以下の金額に収まりました。
まとめ
ココナラでは、本記事でご紹介した仕組みで日々大量配信を行っています。
移行を計画した当初は、外部サービスを超えるものをどうやって作ればよいのだろうと悩みました。
しかしながら、考慮が必要な要素を一つずつ設計に落とし込んだ結果、想像以上によいものを作ることができました。
本記事がアーキテクチャを検討されている方の目にふれ、その布石となれば幸いです。
さらにこの仕組みの詳細を知りたい方は、ぜひ以下フォームよりお気軽にご連絡ください!
ココナラに少しでも興味が湧いたという方も大歓迎です。
入力時間は1、2分です。
ココナラのエンジニアについてもっと知りたい!という方はこちらをご確認ください。
Discussion