デリバリーヒーローの所有する韓国のフードデリバリーサービスBaeminはモノリシックアーキテクチャから、より柔軟なイベント駆動型のマイクロサービスベースのシステムへ移行することで、利用者の急激な増加という課題を見事に乗り切った。
Baeminシステムの基礎はイベント駆動型のアーキテクチャであると先日ブログ記事で紹介された。このアーキテクチャの際立った特徴には、レイヤー化されたイベントサブスクライバーによる懸念事項の徹底した分離と、信頼性向上のためイベントストレージの利用が含まれる。一般的なリレーショナルデータベース管理システム(RDBMS)を活用し、トランザクションアウトボックスパターンを採用することで、Baeminはスケーラブルで信頼性の高い堅牢なフレームワークを構築した。
当初、Baeminはモノリシックアーキテクチャの限界と格闘していたが、会社の規模が拡大するにつれて、その問題が明らかになった。システムは、トラフィックと注文の急増に対応できず、大量のエラーにつながっていた。マイクロサービスへの移行は2019年11月に完了し、次の段階であるイベント駆動型アーキテクチャの採用に向けた準備が整った。このアーキテクチャは、さまざまなマイクロサービス間の疎結合を実現し、システムの回復力と柔軟性を高めるために極めて重要だった。
Baeminのイベント駆動型アーキテクチャの本質は、コマンドやリクエストではなく、ドメインイベントの公開にある。この微妙だが重要な違いによって、異なるシステム間の依存関係を減らしている。従来のコマンドベースのシステムでは、あるサービスを変更すると、別のサービスも変更を余儀なくされ、緊密に結合されたアーキテクチャになってしまう。Baeminはドメインイベントに焦点を当てることで、各マイクロサービスが独立して動作し、そのドメインに関連するイベントをサブスクライブすることを保証する。
Baeminのイベント駆動型アーキテクチャでは、イベントとサブスクライバは3つのレイヤーに編成され、モジュール性と拡張性を確保している。第1のレイヤーであるアプリケーションイベント&ファーストサブスクライバーレイヤーは、Spring Frameworkのアプリケーションイベントを活用して内部的なドメイン固有タスクを管理し、AWS Simple Notification Service(SNS)を介してこれらのイベントを公開する。第2のレイヤーである内部イベント&セカンドサブスクライバーレイヤーは、ドメインのコアではないが必要不可欠なタスクを処理する。例えば、ログインプロセスでは、このレイヤーが他のデバイスからのログアウトのような二次的な処理をする。最後に、第3のレイヤーは、外部イベント&サードサブスクライバーレイヤーと呼ばれ、外部システムが消費するイベントを公開するように設計されている。これらのイベントは、外部システムとの依存関係を作らないように一般化されている。このレイヤーアプローチにより、Baeminは疎結合アーキテクチャを維持しながら、各マイクロサービスが独立して動作できるようにしている。
イベント駆動型アーキテクチャにおける課題の1つは、イベント公開の信頼性を確保することである。Baeminは、イベントストレージシステムを導入することでこれに対処している。このストレージシステムは、ドメインストレージと同じリレーショナルデータベース管理システム(RDBMS)を使用することで、トランザクションによるデータの一貫性を確保している。イベントストレージはバッファとして機能し、イベントをキャプチャして確実に公開する。
このアーキテクチャでは、データの一貫性と信頼性の高いイベント公開を確保するために、トランザクションアウトボックスパターンを採用している。このパターンは、ドメインデータとイベントデータの両方に同じストレージを使用し、信頼性の高いイベント公開メカニズムを可能にする。記事中の以下の図は最終的な設計を示しており、異なるタイプのイベント、イベントストレージシステム、サブスクライバーレイヤー間の相互作用を示している。
それにもかかわらず、最終的な設計では、イベントサブスクライバーのさまざまな層を通じて懸念事項を細心の注意を払って分離している点で注目に値する。イベントストレージを使用して信頼性を確保し、疎結合のためのドメインイベントに重点を置いていることが際立った特徴である。
要約すると、Baeminのアーキテクチャの変革は、スケーリングの問題に取り組んでいる組織に豊富な洞察を提供している。イベントサブスクライバを階層化し、共通のRDBMSに支えられたイベントストレージを活用することで、Baeminは現在のニーズを満たすだけでなく、将来の拡張性と機能強化にも適したシステムを構築した。