マイクロサービス
マイクロサービスアーキテクチャ

第5章 モノリスの分割

接合部:境界づけられたコンテキスト

  • 接合部(seem)
  • 組織に存在する、高水準の「境界づけられたコンテキスト」を特定する
    • 例:カタログ、経理、倉庫、レコメンデーション
  • 上記のコンテキストに従いコードを分割していく
    • 小規模なコードベースで半日、100万行を超えるコードベースでは数週間から数ヶ月かかることも

データベースの分割

  • 外部キー関係の削除
    • クエリの呼び出しが増加する懸念
      • その箇所をどの程度高速にする必要があるのか
    • 外部キー制約は、データベースレベルでなくサービスが管理する制約になる
  • 共有静的データ
    • データベースに格納されたマスタ系のデータ
      • 国コードなど、都道府県もこれに当たる
    • このレコードのためにDBで結合するよりも、サービスごとに静的な列挙型データをコードとして持つほうが理にかなっている
    • 共有データを1つの独立したサービスとする選択肢もあるが、多少やり過ぎ
  • 共有データ
    • 顧客など
    • 共有される別個のサービスにしてしまう
  • 共有テーブル
    • 在庫など
    • カタログ品目と在庫を別テーブルにする
      • カタログサービスと倉庫サービスでそれぞれを管理できるようになる
  • データベースリフファクタリング
    • 下記の順序でサービスを分割していく
      • モノリシックサービス、単一スキーマ
      • モノリシックサービス、スキーマ分割
      • サービス分割、スキーマ分割
    • スキーマ分割が妥当だと判断できた段階でサービスを分割できる
      • 妥当でないと判断された場合でも、コードならより簡単に切り戻すことができる

トランザクション境界

  • サービス分割により、たとえば発注プロセスが単一トランザクションで処理できなくなる
    • いかに一貫性の保たれた状態とするか
  • あとでリトライ
    • 将来的に結果整合性を担保する
  • 操作全体の中止
    • 補正トランザクション(補償トランザクション)
      • 補正トランザクションが失敗したときを考慮する必要がある
        • 補正トランザクションのリトライ
        • 管理者による保守画面、自動化プロセス
        • 監視
      • 一貫性を保つべき操作が増えるごとに把握が困難になっていく
  • 分散トランザクション
    • トランザクションマネージャによりオーケストレーションする
    • 2フェーズコミット
      • 投票フェーズ
        • 分散トランザクションの参加者(コホート)が、トランザクションマネージャにローカルトランザクションを進められるか投票する
        • 全参加者「はい」の場合は、トランザクションマネージャがコミットの指示
        • ひとつでも「いいえ」であれば、全参加者にロールバックの指示
      • コミットフェーズ
    • トランザクションマネージャがダウンしたら、保留中のトランザクションは決して完了しない
    • 保留中のトランザクションはロックを保持する
      • スケーリングが困難
    • アルゴリズムが複雑になるので、独自のアルゴリズムを実装することは勧めません(!)
    • おそらく使わない方がいい
  • どうしたらいいか
    • 分割しなくていい方法を考える
    • 本当に同一トランザクションにする必要があるか
      • 結果整合性の概念で対応できれば、構築やスケーリングが簡単になる場合が多い
    • 難しいから、本当に精一杯やれ
    • 技術的視点でなく、具体的な概念(処理中の注文、のような)を作成して管理することを考える

レポート

  • スキーマが分割されてしまうと、レポートの作成が難しくなる
  • 目的に適った方法で対応することが必要になる
  • ※細かくは割愛

変更のコスト

  • 小さな変更を漸進的にやる
  • コードベース内のコードの移動:コスト小
  • データベースの分割
    • 作業量大
    • ロールバックも複雑
  • サービス間の結合を解く変更
    • 作業量大

まとめ

  • コンテキスト境界を見定める
  • コンテキスト境界に従ってDBの結合を解いていく
  • DBの分割、サービスの分割の順に進める
  • トランザクションの分割は、特に影響が大きい
    • 結果整合性を担保できる程度の分割にする
    • 担保できる範囲から漸進的にすすめる