もりはやメモφ(・ω・ )

インフラなエンジニアからSREへ

マイクロサービスアーキテクチャ本の感想(5章)

そろそろ正月気分も抜けてきました。 O'Reillyのマイクロサービスアーキテクチャ本感想の第5回です。

5章「モノリスの分解」を読んで

4章の統合に対し、5章では既存のモノリシックなアプリケーションをどうやって分割していくかの話になります。

コンテキスト境界再び

モノリシックなアプリケーションを分割するためには、アプリケーションの接合部(seam)を探し出すこと、接合部としてはBC(コンテキスト境界)がわかりやすいのでおすすめとあり、BCを洗い出した後の流れが語られます。

  1. BC(コンテキスト境界)を特定する
  2. 各コンテキストを表すパッケージの作成
  3. 既存コードを各パッケージへ移動
  4. 取り残されたコードから新たにBCを特定 ※以後繰り返し

このフローによってコードベースを接合部に合わせて整理すると捗るそうです。

なぜ分解するのかを考えながら行うことが大事

モノリスを分解するということは、大理石を削る行為に似ているとし、勢いよく削ろうとすると全体が想定外に割れてしまうと警告があり、そのうえでコードベースをさらに分解する指針として以下が挙げられています。

  • 変化の速度
    • 更新が大量に走る処理はそれ自体が分割の対象になる
  • チーム構成
    • チームの地理的な要素(コンウェイの法則もあると思う)
  • セキュリティ
    • 転送データ、格納データ、監視などの観点で適切に保護ができるようになる
  • 技術
    • 技術特異性の話。新しいライブラリ、ミドルで最適化が可能になる

データベースは依存関係の塊です

structure101のようなツールで依存関係をグラフ化すると接合部を見つけるのが捗るぜ、そして大抵の場合はデータベースが最も依存関係の多いポイントだ(意訳)というノリで従来のRDBのあり方に切り込んでいきます。

  • 外部キー関係は削除しよう
    • 品目、帳簿といったテーブルは、品目管理サービス、帳簿管理サービス専用テーブルとして外部キーを削除する
    • 従来のRDBより性能(処理速度)は落ちるが許容できるか判断しよう
    • 品目テーブルと帳簿テーブルのデータ整合性が一致する必要があるか、サービス要件は技術者が考えることではないのでエスカレしよう
      • (確かに商品名が変わったとして、商品名変更前の帳簿には古い名前が載っていても良い気はする)
  • 共有静的データの取り扱い
    • 案1,各サービスで重複して持ってしまう(ハードコーディングするケースもよくあるとか)
    • 案2,サービス化してしまう
  • 共有データはサービス化すべし
    • データベースで暗黙的にモデル化されているドメイン概念
  • 共有テーブルは分割して各サービスに返す
    • (正規化が可能なテーブルだと思う)

この節は自分の携わるシステムのDBの思い浮かべながら読んだのですが、アプリケーション側というか、開発者への負担は相当な物になるなあという印象。

分割は段階的にやっていこう

サービスの分割と、データベース内のスキーマ分割のどちらから行うべきかという話です。適切な順番としては以下としています。

  1. DBのスキーマを分割
  2. アプリケーションを分割

理由はアプリケーションコードを一緒にしておくことで、コンシューマに影響を与えることなく変更を戻せるためです。(アプリケーション側にも変更は必要のはずで、DBへのクエリだけ変えると理解した)

トランザクションはマイクロサービスでは大変だ

分散システムでのトランザクションの担保は、2フェーズコミットやリトライ、ロールバックなど考慮すべき点が多いとし、結論としては以下3点に集約されます。

  1. 本当に単一のトランザクションで行う必要のある処理かを見直す
  2. 単一のトランザクションが必要な処理を分割させずに済む方法を探す
  3. 分割が必要ならトランザクション事態を表す概念を生成する(処理中のhoge、といったステータス)

読んでいて"CAP定理"の話だなと思いましたが、"CAP定理"という言葉は出てきませんでした。

KPIなどのレポート用データベースの取り扱い

よくあるユースケースとして、レポート用のデータベースは複数のデータを結合することが求められますが、どう扱うと良いのかという話です。

  • サービスを介してAPIで呼び出す
    • 一見よさそうだが、大量データ(全ユーザなどの)の取り扱いにRESTは向いていない課題がある
  • データポンプ
    • レポート用のDBへ、必要なデータを定期的にコピーする
    • S3を使ってJSONファイルで渡すといった事例もある
  • イベントデータポンプ
    • レポート用のDBへ、データ変更が発生するなどのイベントをトリガとしてデータをコピーする
  • バックアップデータポンプ
    • NetfrixのCassandraのデータをバックアップする事例から
    • S3とHadoopを利用する後のOSSAegisthus
      • Aegishusは2018/1/11時点ではメンテナンスモードで今後機能拡張されない様子
  • リアルタイム
    • fluentdやlogstashなどを利用したリアルタイムデータ転送(本では具体的なツール名はでていないけど)
    • 今後加速すると著者は予想している

変更コストと根本原因を意識する

  • 変更コスト
    • 最小の影響範囲で失敗できるポイントから変更していく
  • 根本原因
    • モノリシックになることは悪いことではない
    • サービス初期開発時は作りやすさからモノリシックになる、それはOK
    • 適切なタイミングで分割を行うことが大事

5章の感想

本章はDB分割のところを大変面白く読みました。コンテキスト境界を意識して大きな枠から分割していくイメージは言葉だけで分かった気になっている感覚があります。一方でDB分割は自分の業務に近いところでもあり、業務を想定しながら具体的な分割方法を検討する良い機会にもなり、そしてそれが非常に苦労する道のりだという知見が得られた章でした。