- Googleが100%の信頼性のサービスを構築しようとしてるのは違う
- 極端な信頼性はコストになる
- 安定性を最大化することは、新機能開発の速度やユーザにプロダクトを届ける速度を制限し、コストを増大させる。
- コストはチームが提供できる機能の数を減らす
- ユーザが高い信頼性と極限まで高められた信頼性の違いに気づくことは普通はない
- ユーザー体験は、大抵の場合より信頼性の低いコンポーネントに影響を受ける
- 例えば、携帯の通信網だったりデバイスだったり
- 「99%の信頼性のスマートフォンを使っているユーザは99.99%と99.999%のサービスの信頼性の違いが分からん」
- これらのことから、稼働時間を最大化するよりも'サービスが利用不可能になるリスク'と'素早いイノベーションや効率的なサービス運用という目的'のバランスを取ることを目指す
- それによって、ユーザ全体の幸福度を機能やサービスやパフォーマンスといった観点から最適化する
- システムの信頼性が低いとユーザの信頼は一気に下がる
- システムが落ちたりする機会を減らしたい
- でも、経験的にシステムを構築する際にはコストは信頼性の増加に比例しては増えない
- 信頼性増加のための改善は、前回の施策の100倍のコストがかかるもの
- コストがこんなにかかるのには2つの側面がある
- 不要なマシンリソースのコスト
- メンテナンスの際に、システムをオフラインにできたり、コードブロックを保持する余裕ができる ここわからん
- 機会のコスト
- コストは組織がエンジニアリングリソースを、ユーザに直接届けるためではなくて、リスクを軽減する機能やシステムを構築するのに割り当ててた時に発生する
- こういうエンジニアは、ユーザのための機能とかプロダクトのために働いてないから?
- 不要なマシンリソースのコスト
- SREでは、サービスの信頼性をリスクを管理することで管理する(大事っぽい)
- リスクは徐々に変化するものとして概念化する
- より高い信頼性を組み込むことと、サービスの適切な耐久性を見つけることを同じくらい重要視する
- そうすることで、どのサービスでリスクを取るかを特定するためのcost/benefit分析ができる
- 目的は、サービスによって生まれるリスクとビジネスが負担する意思のあるリスクの程度をそろえること
- サービスの信頼性をあげることに取り組んではいるが、必要以上にはやらない
- 99.99%の目標を設定したら、それは超えたいけど、過剰にはやらない
- やり過ぎると、新機能追加や技術的負債の返済やオペレーションコストの削減の機会を逃す
- ある意味で、可用性目標を最大と最小両方として見てる
-
Googleの標準的な習慣として、最適化したいシステムの状態を表現する目的のメトリックを定める
- 目的を定めることで現状のパフォーマンスを評価したり、改善・改悪をトラッキングできる
-
サービスのリスクに関しては、すべての要素をどのように単一のメトリックに落としこむかは明らかではない
- サービスの障害いろんな影響を与える
- ユーザの不満、実害、信頼の消失
- 直接的、間接的な収入の消失
- ブランドや評判への傷
- 望まない報道?
- 測定するの難しい
- サービスの障害いろんな影響を与える
-
問題を様々なシステムに関して追跡可能にするために、「計画外のダウンタイム」に着目する
-
リスク許容度を計画外のダウンタイムの許容レベルで表現する
- 通常はシステムの可用性で表現, 99.9%とか
- 式的には、3-1のやつ
- この式をつかって一年間に許容できるダウンタイムを計算する
- 例えば、99.99%の目標に対しては52.56分のダウンタイムが許される
-
Google的には時間に基づいてた可用性のメトリックは意味を成さないらしい
- あるサービスで世界の何処かでは動いているとか考えがち
-
だから、リクエストの成功率を使ってる(式3-2)
- 2.5Mリクエスト/日に対して99.99%の可用性目標だと、250エラーまでが許される
-
典型的なアプリケーションにおいては、全部のリクエストが等価なわけではない
- 新規ユーザのサインアップリクエストと新規メールのポーリングリクエストの失敗は違う
- それでも、大抵の場合にはエンドユーザの視点から見て計画外のダウンタイムを近似する値として、有効
-
計画外のダウンタイムをリクエスト成功率で定量化することは、エンドユーザに直接サービスしないものにも有効
- バッチとか、ストレージシステムとか
- 大抵のシステムでは成功と失敗がちゃんと定義されてる
- バッチシステムの例
- 定期的に顧客DBから情報を抽出、変形して、分析のためのデータウェアハウスに挿入するもの
- 正常に処理されたレコード数と正常に処理されなかったれコード数をつかって計算できる
- フォーマルな環境セーフティクリティカルなシステムにおいては、プロダクトやサービス定義に組み込まれる
- Googleにおいては、明確に定義されることは少ない
- サービスのリスク許容度を特定するためには、SREはビジネスゴールを、エンジニアリングできる目的に変換するためにプロダクトオーナーと協力しないといけない
- ビジネスゴールはパフォーマンスや信頼性に直接的な影響を持つ
- コンシューマーサービスは明確なプロダクトオーナーをもつが、インフラ的なサービスはそうではない
- それぞれの場合について考えていく
- コンシューマーサービスには、大抵の場合アプリケーションのビジネスオーナーの役割のプロダクトチームがいる
- Googleでも検索、マップ、ドックスにそれぞれいるらしい
- プロダクトマネージャーはユーザとビジネスを理解して、プロダクトを市場で成功させることに責任を持つ
- プロダクトチームがいる場合、そのチームはサービスの信頼性の要件を議論するのに最も適したリソースである
- プロダクトチームがいない場合には、エンジニア自身がこの役割を果たしている場合が多い
- サービスのリスク許容度を評価する際に考慮すべき点
- どの程度の可用性が求められるのか
- 異なるタイプの障害はサービスに異なる影響を与えるのか
- 連続するリスクを抱えたサービスを見つけるためにサービスのコストをどのように使えるのか
- 他に考慮すべき重要なサービスメトリックは何か
- Googleのサービスでは、可用性の目標水準はサービスが提供する機能や市場においてどのようなポジションにいるかによって変わる
- 考慮すべき問題
- ユーザはどの程度の水準のサービスを期待しているのか
- サービスは直接的に収入につながるか(ユーザのものも含む)
- 有料サービスなのか、無料サービスなのか
- 市場に競合がいる場合、競合が提供するサービスの水準はどの程度なのか
- サービスはtoBなのかtoCなのか
- Google Apps for Workを例に
- ユーザはほとんどがエンタープライズ
- 日常の業務を行うのに必要なツールの提供をGoogle Appsに依存してる
- つまり、Google Appsの機能停止はGoogleだけでなく、ユーザ企業の機能停止になる
- 外部的な四半期の可用性目標99.9%と、さらに強固な内部的な目標、外部目標を提供するのに失敗したさいの罰則を定める
- YouTubeの場合は対照的
- 2006年に買収された時には、Googleの事業のライフサイクルからみて異色だった(まだ成長期だったとか?)
- 素早いな機能開発が重要だったので、可用性目標を低めに設定した
- サービスに対して障害の型を予測することは考慮すべき重要な点
- サービスのダウンタイムに対してビジネスはどの程度の弾力性があるか
- 一定の低い割合での障害発生か、時々の全サービス停止のどちらがサービスにとって良くないか
- エラーの数的には同じになるかもしれないが、ビジネスに対する影響は違うかもしれない
- いい例
- 完全な機能停止と部分的な機能停止の違いのいい例として個人情報を提供するシステムがある
- 連絡先管理アプリケーション
- 断続的にプロフィール画像のレンダリングに失敗する場合
- ユーザ体験は良くない、SREは問題修復に取り組む
- プライベートな連絡先情報が他のユーザに露呈する場合
- プライベートなデータの露呈は基本的なユーザの信頼を簡単に失ってしまう
- 結果として、完全なサービス停止はこの場合のデバッグとかクリーンアップフェーズには有効
- 断続的にプロフィール画像のレンダリングに失敗する場合
- メンテナンス期間中に定期的な機能停止が許容される場合もある
- Googleだと数年前のAds Frontendがそうだったらしい
- 広告キャンペーンをセットアップ、設定、実行、監視するサービス
- 通常の業務時間中に使われる性質がある
- 時々、定期的にメンテナンス期間という形で機能停止させることは許容できると判断
- これを計画外のダウンタイムではなく、計画的なダウンタイムとして扱う
- Googleだと数年前のAds Frontendがそうだったらしい
- サービスの適切な可用性目標を決定するための重要な要因
- Adsはリクエストの成否が直接収益と損失になるのでこのトレードオフを考えるのに特にいい
- 可用性目標を定めるための質問
- 可用性目標の9を増やしてシステムを構築運用しようとしたら、収入の増加はどれくらいになるのか
- 追加収入はその信頼性に達するためのコストを埋め合わせできているか
- 具体例
- リクエストは同等の価値を持つ
- 可用性目標の改善提案:99.9% -> 99.99%
- 提案による可用性の増加:0.09%
- サービスの収益:$1M
- 可用性改善の価値:$900
- 1つの9を増やすための改善にかかるコストが$900に収まるのであれば、改善には価値がある
- 収まらないのであれば、コストは収益の増加を超過する
- 信頼性と収益の変換関数が無いときには目標設定が難しくなる
- インターネット上でISPのバックグラウンドエラー率を考慮する方法がある
- もし、障害がエンドユーザ視点で計測できて、サービスのエラー率をバックグラウンドのエラーレート以下に抑えることができたなら、ユーザのインターネットコネクションのノイズ以内にエラーをおさえることができる
- Google曰く、ISPやプロトコル間に有意な差はあるが、計測の結果ISPのバックグラウンドのエラー率は0.01か1%の間に収まるらしい
- インターネット上でISPのバックグラウンドエラー率を考慮する方法がある
- 可用性以外のメトリックと関連付けてサービスのリスク許容度を調査するといいことあるよ
- どのメトリックが重要だったりそうでないかを理解することで、リスクを取ろうとした時に自由度が出てくる
- Googleの広告システムにおけるレイテンシの例
- Googleが検索をランチしたときの際立った特徴はスピードだった
- そのため、AdWordsの重要な要件に「広告が検索体験を遅くしてはいけない」というものがあった
- この要件はずっと変わらないらしい
- AdSenseの例(AdWordsとは違うレイテンシに関する目標がある)
- コンテンツターゲット広告を挿入するときに、サードパーティのページのレンダリングを遅くしない
- レイテンシ目標は、あるサイト運営者のページがレンダリングされる速度に依存している
- AdSenseの広告はAdWords広告よりも数百ミリ秒遅くても良い
- 緩めのレイテンシの要求はプロビジョニングにおいて多くのスマートなトレードオフを設けることを可能にする
- それによって、通常のプロビジョニングに対して大幅なコスト超過をおさえることができる
- レイテンシの変化を緩和するアドセンスに対するある程度の鈍感さを考慮すると、地理的にサーバリソースを統合したり、オペレーションのオーバーヘッドを削減することができる
- インフラストラクチャコンポーネントを構築し、実行するための要件はコンシューマ向けの要件とは違う
- 基本的な違いは、様々なニーズを持った複数のクライアントを持っていること
- BigTableの例
- いくつかの消費者サービスにおいては、ユーザリクエストの経路でBigTableから直接データを提供する
- 低レイテンシと高い信頼性が必要
- オフライン解析を実行するために利用するデータのリポジトリしてのBigtableを利用する
- 信頼性よりもスループットが大事
- これら2つの例のリスク許容度はかなり違う
- いくつかの消費者サービスにおいては、ユーザリクエストの経路でBigTableから直接データを提供する
- 双方のユースケースのニーズを満たす方法はすべてのインフラストラクチャサービスを極めて信頼性が高いように設計すること...
- 実際には、リソースを大量に使う傾向にあるのであまりにも高価
- 異なるユーザの様々なニーズを理解するためには、BigTableのユーザのリクエストキューの理想的な状態に目を向ける
- 低レイテンシのユーザはBigTableのリクエストキューが空で有って欲しい
- システムが未処理の要求を到着後すぐに処理できるようにするため
- 実際、非効率なキューイングによってレイテンシが上がる
- オフライン解析に関わるユーザはシステムのスループットに興味がある
- リクエストキューが空であってほしくはない
- スループットを最大にするためには、BigTableは次のリクエストを待つ間アイドル状態であるべきではない
- こんな感じで、障害?の定義がユーザセットによって異なる
- 低レイテンシを望むユーザの成功状態?はオフライン解析を望むユーザの障害になる
- 費用対効果の高い方法で競合する制約をみたすための方法
- インフラストラクチャを分割して、複数の独立したレベルで提供する
- BigTableの例だと、低レイテンシクラスタとスループットクラスタ
- 低レイテンシクラスタは、低いレイテンシと高い信頼性を必要とするサービスに操作、利用されるように設計する
- 短いキューの長さを保証して、厳格なクライアントの分離要件を満たすために、競合を減らし、冗長性を増加させるためにかなりの余裕をもってプロビジョニングされる
- スループットクラスタは、レイテンシに対するスループットを最適化して、常に動作し、冗長度を低くプロビジョニングする
- 実際、この要求を満たすコストは低いらしい、前者の10%-50%くらいのコスト
- BigTableの規模だと、このコスト削減幅は顕著に現れる
- 低レイテンシクラスタは、低いレイテンシと高い信頼性を必要とするサービスに操作、利用されるように設計する
- インフラの鍵となる戦略は、明確にレベルを分けてサービスを提供すること
- クライアントがリスクとコストで妥協点を見つけることができる(自分たちがAWSとか使うときみたいなイメージ)
- 明確にサービスのレベルを分割することで、インフラストラクチャの提供者は、あるレベルのクライアントにサービスを提供するのに必要なコストを外部化できる
- クライアントが、自身のニーズを満たす最低のコストでサービスのレベルを選択する動機付け
- Google+の場合だと、
- ユーザのプライバシーに関わるような重要なデータは、高可用性で世界的に一貫性のあるデータストアに配置
- ユーザ体験を高めるような補助的なデータは、安くて信頼性の低いようなデータストアにおいたりする
- これまでの話は、同一のソフトウェアとハードウェアを使って実現していることに注意
- 様々なサービスの特性を調整することで、様々なサービス保証を提供することができる
- 特性としては、リソースの量、冗長性、地理的なプロビジョニングの制約、インフラストラクチャ・ソフトウェアの設定
- 様々なサービスの特性を調整することで、様々なサービス保証を提供することができる
- 本の他の章では、製品開発チームとSREチームの間の緊張がどのように発生するかについて議論してる
- チームは違うメトリックで評価される
- 開発チームは、開発の速度で評価される
- SREチームは信頼性で評価される
- このチーム間の情報の非対称性が緊張を増幅する
- 開発チームはコードを書いて、リリースすることに重きをおいている
- SREチームは、サービスの信頼性やプロダクトの状態を見てる
- チームは違うメトリックで評価される
- 代表的な緊張の例
- ソフトウェアの耐障害性
- 予期せぬ出来事に対してソフトウェアをどの程度耐えれるようにするか
- 弱すぎると脆すぎて使えない
- 強すぎると誰も使いたくないもの(安定性はある)
- 予期せぬ出来事に対してソフトウェアをどの程度耐えれるようにするか
- テスト
- 少なすぎると恥ずかしい感じの機能停止や個人情報の流出
- 多すぎると市場を逃す
- pushの頻度
- すべてのpushは危険。リスクを減らすためにどの程度取り組むべきか、あるいは他の仕事をすべきか
- Canary duration and size
- 典型的なワークロードのサブセットで新しいリリースをテストすることはcanaryingという
- どれくらい待つべきか、canaryはどの程度大きいか(サブセットの大きさとかかな)
- ソフトウェアの耐障害性
- チームの情報の非対称性への取り組み
- リスクと労力の境界がどこにあるかみたいな
- バランスが最適だと証明することは難しい
- 単純に、関わるエンジニアの交渉スキルの問題になってくる
- このような決定は、政治や恐怖や希望によってなされるべきではない
- 最終的な目標は、両チームの合意を得て目的のメトリックを決めること
- こうすることで再現可能な交渉ができるようになる
- 「データに基づいた意思決定は良いぞ」
- 客観的なデータにもとづいて決定を下すために、両チームが協力してSLOにもとづいて四半期のエラーバジェットを定める必要がある
- エラーバジェットは1四半期中にサービスがどれくら不安定で良いかをしめす明確なメトリック
- プラクティス
- プロダクトマネジメントがSLO(4章に書いてるらしい)を定義する。SLOはサービスが4半期ごとにどれくらい稼働しているか(uptime)を定める
- uptimeは中立なサードパーティが計測する(モニタリングシステムのことらしい)
- この2つの数字の差がエラーバジェット
- uptimeがSLOを上回っている場合には新機能がリリースされる
- エラーバジェットの一番の利点は、開発チームとSREチームの共通のインセンティブを提供すること
- これによって、イノベーションと信頼性の適切なバランスを見つけることができる
- リリース速度の調整に使われている
- SLOを満たしてたらいけいけどんどん
- エラーバジェットを拡大する必要があるほどに、SLOを侵害したら追加のリソースを投入したりするまでリリースはやめる
- リリースを完全にやめなくても、リリースをゆっくりにしたり、エラーバジェットが回復する地点まで巻き戻す方法もある
- 例えば、開発チームがテストを省略してリリースサイクルを早めたくて、SREチームに余裕がある場合にはエラーバジェットが指標になる
- エラーバジェットが大きければ出せばいいし、小さければ開発チームはテストに時間をかけたり、サイクルを遅くするべき
- 開発チームが自治できるようになる。エラーバジェットのおかげでリスクを認識、管理できるから。
- ネットワーク障害とかの場合は?
- これも勘定にいれる
- 全員がuptimeに対して責任をもっているから
- エラーバジェットは、過剰に高い信頼性目標にかかっているコストを浮き立たせるのにも役立つ
- そのような場合はSLOを引き下げる