🐶

マイクロサービスにおけるトランザクション管理のまとめ

に公開

はじめに

マイクロサービスアーキテクチャでは、サービスごとに独立したデータベースを持つのが一般的です。そのため、複数のサービスをまたいで一貫性のあるデータ更新を行うには、モノリシックなシステムと比べて特有の課題があります。
本記事では、マイクロサービスにおけるデータ整合性の考え方とその手法についてまとめてみました。

データ整合性

マイクロサービスアーキテクチャにおけるデータ整合性は以下の2つに分類されます。

強整合性

  • すべてのサービスのデータが常に最新のデータを持つことを保証するモデルです。
  • 変更中のデータが完了するまで、他のサービスは古いデータが参照できないことを表します。

結果整合性

  • データが更新されても、その変更が全てのサービスのデータに即座には反映されないことを許容するモデルです。
  • 変更中のデータが完了していない間も、他のサービスは古いデータを参照できることを表します。いずれ時間が経過すれば、全てのサービスのデータは最終的に一貫した状態になることを保証します。

トランザクションの種類

ローカルトランザクション
ローカルトランザクションは、単一のデータベースやリソースに対して行われる操作を指します。1つのサービス内で完結するトランザクションであり、ACID 特性を容易に保証できます。マイクロサービスアーキテクチャでは、各サービスが自身のデータベースを持つため、このローカルトランザクションの利用が推奨されます。

グローバルトランザクション
グローバルトランザクションは、複数の異なるデータベースやリソースにまたがる操作を一貫して処理するためのトランザクションです。これは、システム全体で強整合性を保つことを目指すアプローチです。代表的な実装プロトコルとして2フェーズコミット (2PC) などがありますが、これは分散環境でのパフォーマンスボトルネックや可用性の低下を引き起こす可能性があり、マイクロサービスアーキテクチャでは一般的に推奨されません。

データベース間の同期

ローカルトランザクションを利用する場合、複数のサービス間でデータの同期を取る必要があります。そのやり方として以下があります。

TCC (Try - Confirm/Cancel) パターン
複数のサービス間でのトランザクションを管理するための設計パターンです。これは、処理を実行する前にリソースを仮確保 (Try) し、その後に確定 (Confirm) または取り消し (Cancel) を行うことで整合性を保証します。

  • Tryフェーズ: 各サービスが必要なリソースを仮確保したり、操作の事前準備を行ったりします。この時点ではまだ実際のデータ変更はコミットされません。
  • Confirmフェーズ: 全てのサービスの Try フェーズが成功した場合に、仮確保したリソースを確定し、実際のデータ変更をコミットします。
  • Cancelフェーズ: いずれかの Try フェーズが失敗した場合や、処理を中断する必要が生じた場合に、既に仮確保した全てのリソースを取り消します。

Saga パターン
複数のサービスにまたがる一連のトランザクション処理を実現するための設計パターンです。
これは、各ローカルトランザクションが成功すると仮定して処理を進め、途中で失敗が発生した場合に、既に完了した処理の影響を元に戻す補償トランザクションを実行することでデータ整合性を確保します。

Saga パターンの実装には、主に以下の2つの方法があります。

  • オーケストレーション
    オーケストレーターと呼ばれる中央のサービスが全体のトランザクションフローを管理・調整するアプローチです。オーケストレーターが各サービスに処理を指示し、その結果に基づいて次のステップを決定します。
    • 処理フローの全体像が明確で、管理やデバッグが比較的容易
    • オーケストレーターが単一障害点になる可能性がある
    • オーケストレーターが特定のサービスに依存するため、サービス間の結合度がコレオグラフィーより高くなる傾向がある
  • コレオグラフィー
    各サービスがイベントを公開し、他のサービスがそのイベントを購読して次の処理を開始するという、イベント駆動型のアプローチです。オーケストレーターが存在せず、各サービスが自律的に連携します。
    • サービス間の結合度が低く、高い疎結合性を実現できる
    • 新たなサービスを追加する際、既存のサービスに影響を与えにくい
    • 処理フローが複雑になると、全体像の把握やデバッグが難しくなることがある
TCC パターン Saga パターン
前提 事前にリソースを仮確保し、失敗時は取り消す 処理を進めながら、失敗時に補償する
失敗処理 Cancel フェーズ 補償トランザクション
リソースロック Try フェーズでリソースを予約(ロック)する 長時間ロックしない
スケーラビリティ 低い 高い

おわりに

マイクロサービスアーキテクチャにおけるデータ整合性の管理は複雑ですが、本記事で紹介した結果整合性の考え方と、TCC パターンや Saga パターンといった手法を適切に使うことで、スケーラブルで堅牢なシステムを構築できるかと思います。

参考文献

Discussion