【ITニュース解説】Going Event-Driven? Read the Bill First.
2026年10月10日に「Dev.to」が公開したITニュース「Going Event-Driven? Read the Bill First.」について初心者にもわかりやすく解説しています。
ITニュース概要
イベント駆動アーキテクチャは非同期処理に優れるが、設計次第で高額な費用が発生する。イベント数、コンシューマ数、データ量が増えるとコストは跳ね上がるため、事前に費用の試算が重要だ。非同期処理や大規模なスケーラビリティが必要な場合に限り利用を検討すべきである。
ITニュース解説
多くのシステムエンジニア志望者が、システム設計の新たな潮流として「イベント駆動アーキテクチャ」という言葉を耳にすることがある。これは、サービス間の連携を効率的に行うための洗練された手法として注目されているが、その導入には、目に見えにくいコストの側面が存在する。システムを設計する際、「美しさ」と「経済性」は必ずしも一致しないという現実を理解することは重要である。
私たちがシステムを構築する際、多くの場合、サービス同士が直接通信する「HTTP(REST)呼び出し」を用いる。例えば、オンラインストアで顧客が購入ボタンを押したとき、注文サービスが決済サービスを呼び出し、決済サービスが不正検知サービスを呼び出すといった一連の流れだ。この方式では、もし途中のサービスで問題が発生したり、処理に時間がかかったりすると、顧客の操作全体が停止し、待たされることになる。これは、あたかも個々のサービスはマイクロサービスとして分離されているのに、全体としては一つの塊(モノリス)のように振る舞ってしまう「分散モノリス」と呼ばれる問題を引き起こす可能性がある。サービスの応答が遅れると、ユーザー体験が悪化し、システムの信頼性にも影響を及ぼしかねない。
イベント駆動アーキテクチャは、この同期的な待ち合わせの問題を解決する一つの方法だ。ここでは、サービスAが何かイベント(「注文が確定した」など)を「イベントブローカー」と呼ばれる仲介役(例えば、KafkaやAmazon EventBridgeなど)に発行すると、サービスAは自身の処理をすぐに終えて次のリクエストに応じることができる。そのイベントに興味がある他のサービス(例えば、確認メール送信サービス、分析データ更新サービス、ポイント付与サービスなど)は、イベントブローカーからイベントをそれぞれ独自のタイミングで受け取り、自身の処理を実行する。これにより、サービスAは他のサービスの処理完了を待つ必要がなくなり、システム全体の応答性が向上し、より多くのリクエストを処理できるようになる。
しかし、全ての処理がイベント駆動アーキテクチャに適しているわけではない。イベント駆動が真価を発揮するのは、主に二つの状況である。一つは「サービスAが、サービスBがその情報で何をしたかを知らなくても、自身の仕事を完了できる場合」だ。例えば、注文がデータベースに書き込まれることはすぐに成功する必要があるため、これは同期的な処理が適切である。しかし、注文後の確認メールの送信や分析データの更新、ポイントの付与などは、顧客が購入ボタンを押したその瞬間に完了する必要はない。これらはイベントとして発行し、別のサービスが後で処理すれば良い。もう一つは「トラフィックが急増する可能性がある場合」だ。同期的なAPIは突然の大量アクセスで負荷がかかりやすいが、イベントブローカーは急増したリクエストを一時的に受け止めることで、後続のサービスが処理可能なペースでデータを消化できるよう、システムの「衝撃吸収材」として機能する。
イベント駆動アーキテクチャのコストを理解することは、非常に重要だ。イベント駆動システムでは、発行されるイベントの数、そのイベントを受け取るサービスの数(ファンアウト)、そしてイベントに含まれるデータのサイズ(ペイロードサイズ)の三つの要素が、直接的に請求額に影響する。これは、コードを一行も書く前に、ホワイトボード上で概算できるものだ。
具体的な例として、Amazon Web Services(AWS)のEventBridgeとLambdaサービスを使った場合の費用モデルを見てみよう。ここでは、EventBridgeが100万個のカスタムイベント発行に対して1ドルを課金し、ペイロードが64KBを超えるごとに新しいイベントとしてカウントされる。Lambda関数は、100万回のリクエストに対して0.20ドル、そして実行時間とメモリ使用量に応じてコンピューティング費用が発生する。仮に、Lambda関数が128MBのメモリを使い100ミリ秒で処理を完了すると、これは100万回の呼び出しあたり約0.21ドルのコンピューティング費用がかかることになる。
例えば、「注文確定」イベントが100万回発生し、それを12個のLambdaコンシューマーが処理する場合の費用を計算してみよう。 まず、EventBridgeへのイベント発行費用は、100万回で1ドルとなる。 次に、Lambdaのリクエスト費用は、イベントごとに12個のコンシューマーが起動するため、合計1200万回のLambda呼び出しとなり、2.40ドルとなる。 最後に、Lambdaのコンピューティング費用も同様に1200万回の呼び出しに対して計算され、約2.50ドルかかる。 これらを合計すると、100万イベントあたり約5.90ドルとなる。
この費用は、月間100万イベントであれば約5.90ドルと少額に感じるかもしれないが、1億イベントになれば590ドル、10億イベントに達すると5,900ドルに跳ね上がる。さらに、イベントのペイロードサイズが増えれば、EventBridgeの課金も増加する。例えば、256KBのペイロードは64KBの4倍なので、発行費用が4倍になる。
ここから三つの重要なポイントが浮かび上がる。 第一に、「ファンアウト」がコストの乗数となることだ。イベントブローカー自体の費用は比較的安価だが、イベントを受け取るコンシューマーが増えれば増えるほど、それぞれのコンシューマーがLambdaの実行リクエストとコンピューティング費用を発生させるため、コストは指数関数的に増加する。したがって、本当にそのイベントを必要とするサービスだけが購読するように、慎重に設計する必要がある。
第二に、「イベントのペイロードサイズを小さく保つ」ことだ。EventBridgeは64KBごとに課金するため、ペイロードが大きくなると発行費用が大きく膨らむ。イベントには、例えば「order_id: abc123, status: placed」のように、IDと変更内容だけを含めるべきである。もしコンシューマーが完全なデータを必要とする場合は、イベントから受け取ったIDを使ってデータベースやキャッシュから取得する、いわゆる「クレームチェックパターン」を採用することで、コストを大幅に削減できる。
第三に、「無限ループ」はシステムの費用を壊滅させる可能性があることだ。あるサービスがイベントを受け取り、処理し、誤って同じイベントを再発行してしまうと、そのループはシステムが許す限り高速に、無限に繰り返される可能性がある。たとえ100万イベントあたり5.90ドルという費用が小さく見えても、無限ループは通常のトラフィックレートではなく、プラットフォームがスケーリングできる最大速度で実行されるため、請求額はあっという間に膨れ上がる。このような事態を防ぐために、デッドレターキューの設定、リトライ回数の制限、そしてループ検出の仕組みを、システム稼働前に必ず組み込む必要がある。
ただし、これらのコストモデルは単純化されたものであり、実際の費用にはログ出力、データ転送、データベースへのアクセス費用、そしてコンシューマーサービスがさらに呼び出す可能性のある下流サービスの費用などは含まれていない。これらの隠れた費用が、ここで示したモデルの合計額をはるかに上回る可能性も考慮する必要がある。また、月間数百万イベント以下の小規模なシステムであれば、これらのコストはほとんど無視できるレベルであり、むしろ設計の明確さや開発効率を優先すべきだという点も忘れてはならない。
イベント駆動アーキテクチャの導入には、コスト以外の課題もある。例えば、Martin Fowler氏が指摘するように、イベントによってシステム全体の処理の流れが見えにくくなるという問題だ。「注文確定後」に何が起こるのか、コードのどこにも一箇所で明確に示されないため、システムの全体像を把握したり、デバッグしたりするのが難しくなる可能性もある。
また、Kafkaのような自己管理型またはマネージド型のイベントブローカーを使用する場合、その料金体系はイベント数ごとではなく、ブローカーのインスタンス数やストレージ容量に基づいて課金されるため、上記のサーバレスブローカーとは費用計算が大きく異なる点も注意が必要だ。その場合、ファンアウトの費用は実質的に無料に近くなるが、アイドル状態の容量に対しても費用が発生することになる。
結論として、イベント駆動アーキテクチャは、すべてのシステムにとっての銀の弾丸ではない。多くのチームは、必要がないにもかかわらず、あるいは理由が不十分なままイベント駆動に移行しがちである。これは、非同期処理と高いスケーラビリティが真に必要とされる、特定のシナリオでこそ力を発揮する特殊なツールである。もしサービスが、自身の仕事を完了するために他のサービスの応答を必要とするのであれば、従来のHTTP(REST)呼び出しは依然として適切な手段であり、それを使うことに何ら恥じる必要はない。
もしイベント駆動アーキテクチャへの移行を検討する際には、必ず事前にコスト計算を行うべきだ。月間のイベント数、イベントあたりのコンシューマー数、ペイロードが64KB単位で何チャンクになるのかを掛け合わせて概算する。その数字がホワイトボード上で既に不安を覚えるようなら、実際の請求書でその数字を見る前に、設計を見直すべきである。