データベースとメッセージキューの整合性をどう保つか
非同期処理の設計において3つ目のテーマとなるのが、「データベースとメッセージキューの整合性をどう保つか」である。データベースに処理結果を保存すると同時に、イベント通知のためにメッセージを送信する――このような構成では、2つの処理の間にトランザクションが張られないため、一方だけが成功してしまうリスクが生じる。
たとえば、データベースへの保存は成功したが、メッセージ送信には失敗した場合、外部の処理が発火せずに不整合が起こる。逆に、メッセージ送信が成功してもデータベースへのコミットに失敗すれば、「なかったはずの処理」が先に進んでしまう可能性がある。
こうした問題に対して有効なのが、Transactional Outboxパターンだ。木田氏はこの手法について、『Designing Data-Intensive Applications』でも紹介されていると触れたうえで、次のように説明する。
「『outbox』という専用のテーブルを用意し、通常のデータ保存と同じトランザクション内でイベントを書き込む。メッセージの送信はその後に行う——つまり、『保存→送信』というステップを明確に分けることで、整合性を担保することができる」(木田氏)
この方法には、実装上さらに2つのパターンがある。
ポーリングパブリッシャー
ワーカーやバッチジョブを使ってoutboxテーブルを定期的にポーリングし、中に溜まったイベントを検出してメッセージングキューに送信する。シンプルな実装で始めやすい一方、レイテンシやポーリング間隔の設計が課題となる。
トランザクションログテーリング
より高度な手法として、データベースのトランザクションログ(たとえばMySQLのbinlogやPostgreSQLのWAL)をテーリングし、変更をリアルタイムに検知してメッセージを送信する方法もある。こちらは高精度・低レイテンシな処理が可能だが、実装のハードルはやや高い。
木田氏は、「最近では、こうした仕組みを支えるプロダクトやフレームワークも増えてきており、Kafka連携やDynamoDB Streamsなどを活用すれば、導入のハードルも下がってきている」と付け加える。
もうひとつ重要な論点が、重複メッセージの処理だ。たとえばAmazon SQSのようなキューでは、At-Least-Once(少なくとも1回の配信保証)が前提となっており、条件によっては同じメッセージが複数回届いてしまうことがある。
このときに重要なのが、冪等性(べきとうせい:idempotency)の設計である。たとえば「ユーザー登録メールを送る」といった処理であれば、1回送っても3回送っても最悪の影響は小さい。しかし「ユーザーのポイントを加算する」「在庫を減らす」などの処理では、二重実行が致命的な問題を引き起こしかねない。
そのため、もう一つのアプローチとして挙げられたのが「重複メッセージを破棄する」仕組みだ。木田氏は次のように語る。
「メッセージにはユニークなIDを付けて、処理前にデータベースへ保存する。その際にユニーク制約をかけておけば、2度目の処理時には制約違反でエラーが発生し、処理を止めることができます」(木田氏)
メッセージングとデータ保存の両立は非同期処理において避けて通れないテーマだ。Transactional Outboxパターンはその要となる設計アプローチであり、併せて冪等性やユニーク性をいかに担保するかまで含めて考えることが、堅牢な非同期処理設計には欠かせないのだ。
信頼性を高めるスキーマ定義と、4つの実践ポイント
最後に取り上げられたテーマは、非同期処理における「メッセージのスキーマ定義」である。
非同期メッセージングでは、JSON形式を用いてイベントを表現するケースが多く見られる。たとえば「カード発行リクエスト」というイベントであれば、イベントIDやユーザーIDといった属性が含まれる。このような構造に対して、木田氏はJSON Schemaを使ってスキーマを明示的に定義する重要性を説いた。
スキーマを定義しておけば、送信側・受信側の双方でバリデーションを実行できるようになり、メッセージの構造的な正当性が担保される。結果として、非同期処理全体の信頼性を高めることにつながる。
各言語向けにスキーマ定義用のライブラリも充実しており、たとえばRubyではjson-schemaというGemが利用可能である。木田氏は、実際のコード例として、スキーマとイベントを定義し、ユーザーIDの欠落によってバリデーションエラーが発生する動作を示した。
木田氏が紹介した4つのポイントはいずれも、非同期処理に内在する複雑さを構造的に捉え、整合性を維持しながら業務の拡張に対応するうえで重要な視点である。すべてを一度に取り入れるのは難しくとも、1つずつ実践することで、開発の質と速度の両立に近づくことができるだろう。
「今日の内容の中から、明日すぐにでも実践できるものを一つでも持ち帰ってもらえたら」。そう語り終えた木田氏の言葉には、実践に裏打ちされた確かな手応えがにじんでいた。
