はじめに

少し時間が経ってしまいましたが、AWS Dev Day 2023 Tokyo の Day 2 に参加しました。本記事は「E-1: モダンアプリケーションにおける分散トランザクションの動機と実装」についてのレポートとなります。

内容に関して個人的な解釈を多分に含みますが、記事としての読みやすさの観点から言い切り型になっている点についてご了承ください。

セッション内容

モダンアプリケーションに求められる「デプロイの独立性」を切り口として、モノリスからマイクロサービスに分割する上で最終的に残るトランザクションの課題とその考え方について話されていました。以下のような流れです。

  1. デプロイの独立性とモダンアプリケーションの目的
  2. マイクロサービスにおけるデータレイヤーの設計
  3. トランザクション分割の方針
  4. トランザクション分割実装パターン

デプロイの独立性とモダンアプリケーションの目的

モダンアプリケーションに必要とされる Independently Deployable (デプロイの独立性) が確保された状態には以下のようなメリットがあります。

  • チームの自律性が適切に保たれる
  • リリースサイクルを素早く回すことができる
  • 可用性、スケーラビリティ、弾力性を維持しやすい

これらは以下の現代的なビジネス要求を実現するのに役立ちます。

  • 俊敏性
  • スケーラビリティ
  • 弾力性

マイクロサービス、サーバーレス、コンテナ、イベント駆動などを駆使するモダンアプリケーションにおいて、通底する概念が「デプロイの独立性」であり、そのためにサービスを分割していくという流れです。
ただし、サービスを分割することを目的化するのではなく、組織にとっての目標を明確にする、指標化することが大事です。必ずしもサービス分割が正解とは限りません。

マイクロサービスにおけるデータレイヤーの設計

マイクロサービス化のためにドメイン分割を進めていくと、データレイヤー、つまり DB をどうするかという課題に行き着きます。DB がサービス間で複雑に関連している状態はデプロイの独立性を損ねます。このことから、結論としてはデータレイヤーも分割すべきという考え方について話されていました。

ただし、マイクロサービスのような分散アプリケーションではデータの整合性の考え方が変わります。単一 DB で ACID 特性に則っていたトランザクションが、DB が分割されることによってそうではなくなります。つまり、結果整合性の考え方を導入する必要が出てきます。

トランザクション分割の方針

サービスの分割はビジネスドメインの分割と一致させるべきです。ドメイン駆動設計では以下の用語が定義されています。

  •  集約 (Aggregatre)
    • 一貫性 (トランザクション) を保持する必要のある境界
    • 自己完結した状態
  • 境界づけられたコンテキスト (Bounded Context)
    •  関連する集約のコレクション
    • より広い世界への明確なインターフェースを備える

トランザクションが集約ごとに分割されるので、集約と集約の間では結果整合性を検討することになります。結果整合性が受け入れられない場合、サービス境界、つまりビジネスドメインの分割方針を見直したほうがよいかもしれません。

トランザクション分割実装パターン

ここからデザインパターンの紹介でした。

Saga パターン

Saga パターンには以下の 2 つがあります。

  • オーケストレーション
    • 指揮者あり: 指揮者が状態を管理
  • コレオグラフィ
    • 指揮者なし: 個々の振る舞いだけで協調して動作

Saga パターンで重要なのは、処理が失敗した時の補償トランザクションを備え、その機構によってロールバック可能であることや、冪等性を備えていることです。なお、オーケストレーションを実装できる代表的な AWS サービスとして AWS Step Functions が紹介されていました。

イベント駆動アーキテクチャ

イベントとは状態が変更されたことを示すシグナルのことで、非同期的なものです。ドメインで発生したイベントを他のドメインに供給する設計パターンとしてイベントソーシングが紹介されていました。

同一 DB のトランザクション処理

複数サービスで単一の DB を共有するしかない場合のパターンも紹介されていました。密結合かつスケールもしづらい上、サービス A の変更がサービス B に伝播して悪影響を及ぼす可能性があるため、できれば避けたいパターンです。

分散合意

最後に、サービスは分割したいけどトランザクションはまとめたいという無理筋に対応する方法として分散合意系が紹介されていました。これは技術的に非常に高レベルなことのようですが、 AWS での使用例として以下があるようです。

  • Amazon DynamoDB の Multi-Paxos
  • Amazon Aurora のクォーラムシステム

おわりに

モダンアプリケーションに関しては「AWS モダンアプリケーション入門」という書籍をたまたま読んでおり、デザインパターンに関して概要レベルの知識がうっすらある状態でした (言葉からなんとなく思い出せるレベル)
また、サーバーレスアプリの CI/CD 導入に関して業務経験があり、自分自身デプロイの粒度に悩んだ経験があったので、非常に面白く聴講することができました。

モダンなアーキテクチャに関して概念レベルで考える機会がなかったので、そういった意味でよい学びとなりました。今後も業務でモダンアプリケーションのインフラ設計などに携わる機会があると思うので、その際にこのようなトランザクションの観点を上流の段階で提示できたらまた違ってくるだろうなと思いました。