Money Forward Developers Blog

株式会社マネーフォワード公式開発者向けブログです。技術や開発手法、イベント登壇などを発信します。サービスに関するご質問は、各サービス窓口までご連絡ください。

20230215130734

メール送信基盤の最適化:アーキテクチャ再設計で達成した劇的なパフォーマンス改善

はじめに

こんにちは。CTO室基盤アプリケーション部の斉藤といいます。フクロウが好きなので、社内やGitHub上ではフクロウさんアイコンで生息してます。

さて、自分は様々なプロダクトから利用される共通基盤となるマイクロサービスの運用開発を行っています。 去年、メール送信基盤サービスの性能改善のためのアーキテクチャの刷新に取り組み、メール送信速度を3倍以上、レスポンスを約20%高速化、そしてコストを約75%削減に成功しました。この記事では、このアーキテクチャ刷新について紹介していこうと思います。

旧アーキテクチャと課題点

このサービスは当初プロトタイプとして開発されたものだったので、利用プロダクトは少なく、大した性能は要求されていませんでした。 しかし、自分がこのサービスの運用開発チームにアサインされたのと同時期に、1日に数百万件のメール送信をしたい要望が生まれ、最初の性能改善の取り組みが始まりました。この件については「マネーフォワードのこれからのメール送信を支えるマイクロサービス開発」で紹介されています。 この性能改善活動の後も、将来的に全社のメール送信を支えるにはまだまだ性能不足という結論になり、継続的に改善活動を行っていました。その結果、下記のようなアーキテクチャとなり、これでしばらく運用していました。

The old system architecture

このアーキテクチャでは、メール送信リクエストをイベントとして扱い、SNS-SQSを経由してWorkerが非同期にメール送信を行っていました。イベントには多くの情報を入れておらず、基本的にメールデータの授受はAuroraで、書き込み頻度が高くDBへ負荷をかけている処理はRedisに逃すなどして負荷を分散していました。

この時の性能は400rps程度であり、直近の性能要求は問題なく満たせていました。 しかし、運用していく中で下記のような課題が浮き彫りとなり、この形では将来的な要求には応えきれない予測が立ってきました。

  • スケーラビリティの欠如: メールデータの授受がDB経由で行われるので、将来的にスケールアウトしづらくボトルネックになりやすい。
  • コストパフォーマンスの低下: 1日に数百万件のメールを遅延なく送信するために、DBのスペックを高く維持しておく必要がありコストが嵩む。将来的な送信量の増大がコストに重くのしかかることも目に見えていた。
  • 運用コストの増加: 既存アーキテクチャをベースに少しづつ改善を重ねた結果、提供している機能に比べて複雑度だけが上がっていき、それに伴い運用コストが上がっていた。

これらの問題点に加えて、別プロジェクトの影響で需要の急上昇が見込まれたため、その前にアーキテクチャを刷新することを決断し、新アーキテクチャ設計に向けて動き始めました。

新アーキテクチャの設計

再設計されたアーキテクチャは下記のような構成になりました。

The new system architecture

旧アーキテクチャから変わった主な点は下記です。

  • メールデータの授受方式
  • 重複送信の防止のための冪等性担保の仕組み
  • APIに利用する通信プロトコル

メールデータの授受方式の変更

旧アーキテクチャでは、すべてのメールデータはDBを経由して授受されていました。しかし、メール送信の利用実態を調査してみると、実際に送られているほとんどのメールのサイズは十分に小さく、また、メールデータは送信後には利用されていませんでした。これらの事実から、SNS-SQSで送っているイベント情報にそのままメールデータを載せても問題ないことがわかりました。そのため新アーキテクチャでは、メールデータの授受は基本的にSNS-SQSを経由させることにしました。大きいメールデータだけはS3にデータを置きつつ、イベントにデータがどこに格納されているかの情報を追加し、WorkerがS3から取得するようにしています。

また、送信数についても常時高いパフォーマンスを要求されるわけではなく、短時間に集中して送られる傾向があります(例:ビジネス関連のメールは平日朝9時頃のみ大量の送信が発生するなど)。そのため、必要な時に必要な分だけ柔軟にスケールできる方がコストパフォーマンスが良いことがわかっていました。この点も、容易にスケールできないDBではなく、スケーラビリティに優れたSNS、SQS、S3を選択した理由です。

このように、大規模なワークロードにも耐えられるように設計されたSNS、SQS、S3を活用することでスケーラビリティを確保しつつ、DBを廃止することでスケールアウトしづらい問題によるボトルネックを解消することを目指しました。DB廃止により、データの保持コストがほぼなくなり、大幅なコスト削減も期待できました。

冪等性担保の仕組みの変更

旧アーキテクチャでは、DBやRedisを利用して冪等性を担保していました。ここをDynamoDBに変更しています。

DynamoDBにはイベントID、処理状況、ロック期限などの情報を格納しており、これら情報を利用してSQSから受信したイベントは処理していいのかを判断しています。この際に、DynamoDBのConditional putという、条件付きでデータを格納することができる機能を利用しています。すでに処理済みのイベントを受信した、もしくは、他のコンテナが処理中のイベントを受信した場合は、書き込みを失敗させることで、受信したコンテナが処理を継続してはいけないことを認識できるようになっています。この実装により、冪等性が担保される仕組みとなっています。

DynamoDBを冪等性担保の仕組みに利用することで、RDBよりもスケーラブルかつRedisよりも容易にロック機構を実装可能となります。これにより、スケーラビリティの確保や内部的な複雑度の低減に成功しています。

通信プロトコルの変更

前述しましたが、メール送信リクエストは短時間に集中する傾向があり、その時間帯は数百rpsを要求されます。この時、リクエストごとにコネクションを貼り直すのはリソースの無駄となり、あまりよろしくありません。これを解消するためにAPIにgRPCを利用するかどうかを検討していました。 gRPCでは単一のHTTPコネクションを利用して通信を多重化するため、大量のリクエストを受け付ける際に通信コストが低くなる特性があります。また、gRPCだとスキーマファーストの開発となり、将来的な変更に対しても安全に行うことができるだろうという見込みもありました。導入メリットは多いのですが、チームメンバー全員が利用したことがない技術だったため、設計初期には導入に対して慎重になっていました。しかし、社内での利用実績も確認できたため、最終的にはgRPCを採用することに決定しました。

アーキテクチャ刷新による改善結果

アーキテクチャ刷新の効果を測るために、実装後にはパフォーマンステストを実施しました。テスト実施のイメージは下記です。

The performance test architecture

負荷をかけるためのツールはk6を利用し、各種メトリクスなどはDatadogから監視していました(AWSやKubernetes上の各種リソースの情報は基本的にDatadogに流してあるので容易に監視体制を作ることができます)。また、テストのために大量のメールをインターネットを経由して送信してしまうと、ドメインレピュテーションなどにどの程度影響があるかわからなかったので、実際の送信部分は偽物のMTAに流すように変更して実施しました。

旧アーキテクチャはコストなどを踏まえた場合、400rps程度が性能の最大値でしたが、新アーキテクチャではその3倍以上となる1300rpsを超えるパフォーマンスを記録しました(最初のアーキテクチャ改善後と比較すると10倍程度)。このテスト結果もテスト環境への負荷やモックなどの環境整備コストの兼ね合いで中断したものであり、よりスケールさせればまだ上がる見込みのある結果となりました。

また、下記についても改善の効果が表れていました。

  • レスポンスタイム: 旧アーキテクチャと比較して約20%高速化
  • コスト: 現時点で約75%の削減
  • 運用コスト: アーキテクチャ刷新による内部品質の向上とDB廃止などによるメンテナンスコストの削減により、全体的に運用負荷が減少。

結果として、アーキテクチャ刷新前に挙がっていた、スケーラビリティの欠如、コストパフォーマンス、運用コストなどの問題点はすべて解決することができました。

まとめ

去年行われたメール送信基盤サービスのアーキテクチャ刷新について紹介してきました。 稼働しているシステムを1から設計し直すことは初めての経験だったのですが、実際の利用状況やデータ特性などを正確に見極めて設計できるので、より適切な形にアーキテクチャを進化させることができたのではないかと考えています。 なお、新アーキテクチャは昨年末にリリースされ、現在も正常にユーザーの皆さんへメールを送信し続けています。また、直近で要求される性能を超えたパフォーマンスを記録しているので、現在は安心して機能拡充などに人的リソースを割き、社内でのさらなる普及に向けて全力で開発中です。