野次馬エンジニア道

野次馬な気持ちでプログラミングをあれこれと綴ります

Architecting for Scale - Two mistakes high

スキマ時間にコツコツ下記の本を読む。

Architecting for Scale: High Availability for Your Growing Applications

Architecting for Scale: High Availability for Your Growing Applications

概要としては、

  • 可用性 (availability)
  • リスク
  • サービスやマイクロサービスを用いたアプリケーション構築
  • アプリケーションと開発チームのスケーリング
  • スケーリングのためのクラウドの活用

をそれぞれ著者:Lee Atchison *1の経験に基づき詳細に解説している。早速気になったところをメモ書き。一部の章はPreview版が公開されている*2

可用性

可用性とはアプリケーションが行うべきタスクを実行し続けることができる状態にある能力のこと。信頼性とは異なる。例えば、2+3で6が返るようなことが信頼性。可用でないときは、2+3が返ってこない状態。利用可能な状態可用性の低下が起こる要因としては

  • リソースの枯渇
  • 予期せぬ負荷
  • 可動部分の増加
  • 外部の依存性
  • 技術的負債

リスク管理

リスクを特定することなしにリスク管理は行えない。全てのリスクを取り除くことは不可能なのでコストとのバランスとなる。リスクを考える上での発生の可能性(Likelihood)と深刻度(Likelihood)の両面を考えることが重要。当然、起こりやすく深刻度の高いものを解決することが必要となる。リスク管理の基本的なステップは

  • リスクの特定 - システムで考えられるリスクを全て列挙して優先度付けをする
  • 原因の除去 (Remove worst offenders) - もっとも大きい要因を特定し、それに対する対応を計画する
  • リスクの軽減 - 取り除くことができないものの発生の可能性もしくは深刻度を軽減する
  • 定期的な見直し

リスクマトリックス

紹介されていたフォーマット*3

  • リスクID
  • システム名 またはコンポーネント
  • オーナー - 個人かチームか
  • リスクの説明
  • 日付
  • 発生の可能性 ( low, medium, or high)
  • 深刻度 (low, medium, or high)
  • 軽減プラン
  • ステータス
  • ETA
  • モニタリング - このリスクが発生することをモニタリングしているかどうか。
  • 発生時のプラン - このリスクが発生したときに何をするか。インシデントの応対プランよりもマネジメントレベルでのプラン。

早速シートを作ったら関係者の見識を加えてブレスト。開発チーム・サポート・脅威ベクトル・バックログ・パフォーマンス・ビジネスオーナー ・外部のチーム・システムとプロセスとして明文化されているか・技術的負債はあるかなど。

次に発生の可能性と深刻度を設定する。そして計画を立ててタスクとして実行していく。

サービス

ここでサービスとは一つないし二つの製品を支える機能を与える境界を持ったシステムのこと。サービスは改善されたシステムと開発チームにスケーラビリティをもたらすシステム構築を可能とするアプリケーションパターン。

大規模なマイクロサービスベースのアプリケーションの一つの弱点はサービスの不具合。サービスの数が多ければ多いほど可能性が増し、また不具合のあったサービスへ依存のあるサービスも増える。

レスポンスが返ってこない場合の良いアプローチとして、Circuit breaker design pattern - Wikipedia, the free encyclopediaを紹介。

スケーリング

失敗の連鎖、カスケードした依存性を避けるために"Two mistakes high"でシステム構築を行う。ラジコンの例えで、2つ間違いを犯してもリカバリーできるぐらい十分な高さで飛ばすべきという意味。

他には内部的なSLAやサービスのTierについて。

STOSA (Single Team Owned Service Architecture)

スケーラビリティや可用性を犠牲にせずに多くのエンジニアが効率よく一つのアプリケーションを開発するための組織のあり方について。criteriaとしては、

  • サービスやマイクロサービスベースのアーキテクチャに則ったアプリケーションがある
  • 複数の開発チームがそれを開発している
  • アプリケーションの全てのサービスが開発チームにアサインされている
  • 複数の開発チームにアサインされるサービスが一つもない
  • ここの開発チームが一つ以上のサービスを担当するかもしれない
  • チームはサービスに関わる全ての側面(デザイン・デプロイ・テスト・モニタリング・インシデント管理)に責任を持つ
  • サービスはそれらの間にAPIドキュメントも含めて強い境界線が存在する
  • サービスは内部的なSLAを維持し、それらを監視し守られない場合にはサービスのオーナーにレポートする

クラウド

  • MultiAZ。別々のデータセンターとなるのは一つのアカウント内のみ。
  • CloudWatchで十分か? No.ベースラインのみ。サーバやOSの情報(メモリ使用量・スワッピング・ディスクの使用量)。パフォーマンスモニタリング。どのようにユーザに使われているか、エラーなどの情報がいる。
  • リソースのアロケーションにおける二つのカテゴリ。Allocated-capacity resources (EC2, ELB, DynamoDB)。Usage-based resources (S3, Lambda, SES, SQS, SNS) から長所・短所を考える。

Architecting for Scale とは

単に多くのユーザを裁くというだけでなく以下に留意する

  • ユーザ数とその増加に耐える
  • データ量とその増加に耐える
  • アプリケーションで達成したいことがより複雑化することに耐える
  • 開発者が増加してもスピードや効率性、品質が落ちない
  • これらの変更があっても常に可動し続けること

感想

もっとも印象に残ったのは、”Two mistakes high”という言葉。日頃から意識して取り組むと大分違うのではないかと思う。また実践としてアーキテクチャをレビューする際にはこういった項目を漏れなく自分たちのプロジェクトや組織、システム領域やゴールに合わせてチェックすることになるのだと思う。