ソフトウェアアーキテクチャ・ハードパーツ - 読書メモ

「ソフトウェアアーキテクチャ・ハードパーツ ― 分散アーキテクチャのためのトレードオフ分析」を読んだ。仕事でマイクロサービスを扱っているため読むことにしたが、トレードオフを認識した上での判断がとても重要であること。どのような状態がチームとしてよりよい状態なのかの判断軸のようなものを持てた。
何を目的としてどのように行うのか
モジュール化の推進要因の関係性の図があり、これがとてもわかりやすく会社やチームの現在のフェーズにおいて「何をやるべきか」の判断が適切に行える図だとおもう。
以下のような図が記載されており、各項目は以下のように説明されている。

- 市場投入速度を短縮するには、アーキテクチャ上のアジリティ(変化にすばやく対応する能力)が必要
- アジリティは、「デプロイ性」「テスト性」「保守性」を高める必要がある
- 競争優位性は、市場投入速度に加えて、「スケーラビリティ」やアプリケーション全体の「可用性」「耐障害性」を組み合わせることで達成される
会社として求められている部分に焦点をあて、かつチームとして足りていない部分を補うための対策が考えられるとてもよい図だとおもう。モジュール化の推進要因としてこの図は整理されているが、以下の注意書きがある。
P49
アーキテクトは、明確なビジネス上の推進要因が存在しない限り、システムを小さなパーツに分割するべきではない
本書の冒頭にも以下のような注意書きがあり、一貫性を感じる。
P1
アーキテクトは、自分の問題に対する「銀の弾丸」を探し求めてはならない
P2
アーキテクトには、重要な決定の両側にある一連のトレードオフを客観的に判断・評価する能力が求められる
「決して最善のアーキテクチャを狙ってはいけない。むしろ、少なくとも最悪ではないトレードオフの組み合わせを狙おう」
分解と統合
どの単位で分解すべきか、分解の要因。どの単位で統合すべきか、統合の要因を小さなコンポーネント単位から大きくまとめたサービスの単位毎に定義されていく流れがとても素敵。個人的にはすんなり理解できる理論に思えた。
個人的な一番の関心事は、データベースの分解・統合をどのように考えるべきか。ここをちゃんと考えないと後でとても変更が大変になる印象があるためだ。分解・統合のパターン(パーツ)がいくつか紹介されているため実践でも活用できるのがありがたい。
分解・統合パターンの紹介でちゃんとトレードオフを認識できていなかったものとして「共通ライブラリとバージョニング」があった。この部分は読んでおいて良かったと思っている。
P226
粒度の荒い共通ライブラリのクラスファイルに変更が入った場合には、その変更を取り込みたいかどうかにかかわらず、共通ライブラリのバージョンが古くなってしまう
そのため、全てのサービスが最終的にその変更を採用しなければならない
ちいさな機能ベースのライブラリに分割した場合、どの機能がどのライブラリと依存しているかのマトリクス管理が必要になり、分割した泥団子のように見える(分散モノリスと呼ぶ人もいる)
P227
「バージョニングはシンプル」というのは、分散コンピューティングの9番目の誤信
バージョニングは非常に複雑
・バージョン変更の伝達
・古いバージョンの非推奨化
共通ライブラリのためにデプロイ性や保守性を下げてしまう可能性があり、またコミュニケーションコストも爆上がりする。npmパッケージで気軽にversion upして動かなくなる状況と似ているのかも知れない(非推奨化が伝えにくい)。
「Clean Craftsmanship」という書籍に以下の記述があり
P220
偶然の重複は排除すべきではない
本物の重複と偶然の重複の区別は、コードがどれだけ意図を表現できているかに依存する
本物の重複を共通ライブラリとして適切に切り出せるかどうか、境界付けられたコンテキストを抽出できているかによってしっかり見極めなければ共通ライブラリ化は行わないべきだと思う。偶然の重複を共通化してしまう代償はめちゃくちゃに大きい(自戒を込めて)。
雑なメモ
- p55~58
- デプロイ性
- デプロイのしやすさ、頻度、デプロイに伴う全体的なリスク
- もし、マイクロサービスのサービス群を必ず特定の順序でデプロイしなければいけないのであれば、モノリスに戻して苦痛を取り除こう
- スケーラビリティ(Scalability)
- 負荷が増加しても、システムが応答性を維持できる能力
- 弾力性(Elasticity)
- 負荷が瞬間的かつ不規則に著しく増加した場合にシステムが応答性を維持できる能力
- サービスの平均起動時間(MTTS: Mean Time To Startup)の短さに依存する
- 1つのビジネストランザクションを完了するのに、より多くのサービスの相互通信が必要になるほど、スケーラビリティと弾力性にもより悪影響がでる
- サービス間の同期通信を最小限にとどめることが重要
- p188~189
- モジュール性
- システムを個別のパーツに分解すること
- 柔軟かつ多様な使い方が可能なように標準的な単位や観点で構成されていること
- 粒度
- 個別のパーツの大きさのこと
- 適切な粒度
- サービスのクラス数やコード行数ではなく、サービスが何をするのかによって定義される
- サービスの粒度を正しく決定することは難しい
- 粒度分解要因
- サービスの範囲と機能
- コード変動率
- スケーラビリティとスループット
- 耐障害性
- セキュリティ
- 拡張性
- 粒度統合要因
- データベーストランザクション
- ワークフローとコレオグラフィ
- 共有コード
- データ関係
- モジュール性
- p267
- 分散トランザクションではBASEという性質をサポートする(base:塩基性 ↔ acid:酸性)
- BA: 基本的に利用可能(Basically Available)
- S: 柔軟な状態(Soft state)
- E: 結果整合性(Eventual consistency)
駄文
たくさん本を読んでいるが、それをまとめるようなアウトプットが間に合っていない。
ここ数年で、読んだ書籍についてちゃんとアウトプットしないと自分の中で知識が定着しない印象あるためやっていく。