- GoogleのSRE: 最適化に時間を使う
- コンピューティングリソースだけでなく、時間の使い方も最適化する
- トイルに時間を使いたくない
- トイルに関する包括的な話はSRE本の5章参照
- この章でのトイルの定義:
- サービス維持に関するもので、繰り返され、予測可能な一連のタスク
- 本番運用にトイルは避けられない
- メンテナンス: ロールアウト/アップグレード/再起動/アラートへの対処 etc...
- GoogleのSREチームではオペレーションに費やせる時間は50%が限度(トイルとトイル以外の両方を含む)
- 50%という数字はともかく時間の上限を設定することで、トイルを特定し、定量化するのがチームの時間の最適化のために良い
トイルは以下で挙げた特徴に当てはまる傾向がある。
- マニュアル作業
- 例: Webサーバーのtmpディレクトリの利用率が95%になり、エンジニアのアンはサーバーにログインし、削除可能なログファイルがないかどうか調べる
- 繰り返し作業
- 例: tmpディレクトリが一杯になってしまうのは一回限りでは無さそう。それを直す作業は繰り返される。
- 自動化可能
- 例: 「Xにログインし、このコマンドを実行し、出力を確認し、もし...があればYを再起動し...」といった内容の対応マニュアルがある
- ↑はソフトウェア開発スキルを持つ人には擬似コードとなっている. 自動化するのが良い(もちろん根本原因の修正の方が良い)
- 非テクニカル・リアクティブ
- 例: 「ディスク・フル」「サーバー・ダウン」のようなアラートが多いと、生産的なエンジニアリングの気を逸してしまう上に、重大なアラートに気づかなくなってしまう可能性がある。
- 永続しない価値
- タスクの完了は満足感をもたらすが、長期的には同じことの繰り返しのタスクの満足感は良いものではない。
- 例: アラート対応を完了し、HTTPステータスコードが400未満となり正常な状態となった。しかし将来また発生する可能性がある。短期間の価値しか無い。
- システムと同じくらいの速さで成長する
- 様々な種類の運用作業は、基盤インフラのスケーリングと同様に増加していく
- 例: ハードウェアの修復のような物理的作業
- しかし、ソフトウェアやコンフィグ変更のような作業は、本来増加する必要はない
トイルの発生源は上記全ての条件を満たしているわけではないが、トイルは様々な形で発生する. この他にも、チームの士気に及ぼす影響を考慮した方がよい。 トイルはチームの士気を段々下げるし、トイルに費やす時間は深く考えたり創造性のある時間ではない。 トイルの削減することで、他の人間の判断や表現な可能な領域によって、エンジニアの労力がより有効に活用される
by John Looney氏 (FacebookのProduction Engineering Manager)
- とある一連の作業がトイルかどうか、必ずしも明確ではない
- その場しのぎのワークアラウンドのような「創造的」な解決策が正しいとは限らない
- 理想的には、単に問題を隠してしまうような修正ではなく、根本原因への修正に対して報酬を与えるべき
- Googleでの仕事の話 @ 2005年4月
- 壊れたマシンにログインし、その原因調査と修正をしたりしていた
- いつも2万台以上の壊れたマシンが存在することに気づいた
- 最初に調査した壊れたマシン
- Googleでパッチを当てたN/Wドライバの数ギガバイトの不要なログがルートファイルシステムを占有していた
- 同様のマシンが1000台以上あった
- 「全ての壊れたマシンにSSHログインし、ディスクをチェックして、ログを削除するスクリプト」を書こうとした
- チームメンバーはあまり乗り気でく、可能であれば根本原因を修正する方が良いと指摘した
- 中長期的には、スクリプトによって問題の重大さを隠し、潜在的に他の問題が発生する可能性あり、根本原因を直さないことで時間を無駄にしてしまうかもしれない
- サーバーのコストは1時間辺り1ドルほど
- コストはそこまで重要じゃないはず?
- カーネルチームのリリーステストではログの量をチェックしていなかった
- カーネルソースを見るように促され、根本原因となるコード行を発見することができた
- 個人的な計算では、この問題の修正のために開発者に1時間辺り1000ドルのコストをかけていた
- 翌日にパッチが反映され、次週にはカーネルチームのテストが更新された
- 壊れたマシンを毎朝直すというつかの間の喜びの代わりに、適切に問題が解決されたことによる大きな幸福感を得た
-
どのくらいトイルに費やしているのか?
- 経験と直感
- 他の人には分からない
- 人によって捉え方が違うと優先度がつけられない
- トイルの削減には数ヶ月、また何年もかかる場合がある(ケーススタディで説明)
- すると担当者や優先順位の変更があったりする
- トイル削減に集中し続け、長期的なコストを正当化するには進捗の客観的な指標が必要
- 経験と直感
-
トイル削減プロジェクト
- プロジェクトの前に、まずは費用対効果を分析する
- 自動化の開発とメンテ費やした時間に対して時間が減っているかどうか確認するのが重要(図. 6-1)
- 時間が節約できず「不採算」と思われるプロジェクトでも、自動化による他の間接的なメリットのためにやる価値はあるかも
- プロジェクトの前に、まずは費用対効果を分析する
-
図6-1
-
自動化による潜在的なメリットは以下の通り
- 将来のトイル削減(?)
- チームの士気の向上と、精神的疲労の減少
- 差し込みに対する切り替えコストが減ることで、チーム生産性の向上
- プロセスの透明性と標準化の向上
- チームメンバーの技術スキルとキャリア成長の向上
- トレーニング時間の削減
- ヒューマンエラーによる停止の減少
- セキュリティの向上
- ユーザー要求への応答時間の短縮
-
どのように計測すべきか
- 1: トイルを特定すること
- SRE本第5章にトイルを特定するためのガイドラインがある
- 特定するのに最適な担当者は組織によって異なるが、理想的には実際の作業担当者を含むステークホルダーが良い
- 2: トイルに対する人間の作業量を適切に計測できる単位を選択すること
- 「分」や「時」は客観的で分かりやすい。
- トイルに対する作業切り替えコストを考慮すること
- 分散・断片化された作業には別の仕組みの方が良いかもしれない
- 適用されたパッチ数, 完了チケット数, 手動での変更回数, メール数, ハードウェア作業 等
- 単位が、客観的で一貫性があり分かりやすい限り、トイルの計測指標として使うことができる
- 3: これらの測定値を、トイル削減の実施前・実施中・実施後に継続的に追うこと
- ツールやスクリプトを使って、計測プロセスを整備する
- これがトイルにならないように!
- 1: トイルを特定すること
- はっきりとした A or B の分類ではなく、複数当てはまる場合もあり
- 最も一般的なトイル
- コンピューティングリソースの管理
- ストレージ、ネットワーク、データベース etc.
- 新入社員対応、コンフィグ、ソフトウェアアップデート、サーバーの追加や削除
- 無駄なリソースを消してコストを削減する
- コンピューティングリソースの管理
- 社内のユーザーとのチケットでのやり取り
- チケットベースでのビジネスプロセスはビジネス上のゴールを達成するため、チケットトイルが隠れがち
- ユーザーが望むものを手に入れることができる
- トイルがチーム全体に均等に分散される
- トイルが明確に修復を要求していない
- プロセスの自動化を計画していなくても、シンプルにしたり整備したりといったプロセスの改善が可能
- 後に自動化するのも簡単になるし、管理も容易
- チケットベースでのビジネスプロセスはビジネス上のゴールを達成するため、チケットトイルが隠れがち
- 差し込み作業は、システムが動作し続けるため即時対応が必要な整理作業として一般的
- 例: 急なリソース不足(ディスク、メモリ、I/O)を直すために、手動でディスク削除したりアプリケーションの再起動をする
- 他の重要な作業から注意を逸してしまう
- デプロイツールによって、開発環境から本番環境へ自動的にリリースする組織は多い
- コードカバレッジ、コードレビュー、様々な自動テストが自動化されていても、毎回うまく自動で出来るわけではない
- リリースはトイルを発生させ得る
- ツール、リリースの頻度、リリース要求、ロールバック、緊急パッチ、繰り返しや手動の設定変更
- テクノロジーのマイグレーション
- XからYに1回切り替えるだけ済むので、手作業と少しのスクリプトで実行する
- 様々な形のマイグレーションがある
- データストア, クラウドベンダー, VCS, ライブラリ, その他ツール
- 大規模なマイグレーションを手作業でする場合、トイルを含む可能性が高い
- 一回限りなので手作業でしようとする
- マイグレーションを「トイル」ではなく「プロジェクト」として見なそうとする
- マイグレーションはトイルの基準の多くを満たしている
- データベースのバックアップツールを別のデータベースと連携するようにする変更は、技術的にはソフトウェア開発となる
- しかし基本的にはコードのインターフェースを他のものへ変えるリファクタリング
- この作業は繰り返され、大体の場合、バックアップツールのビジネス価値は元と変わらない
- クラウドでもデータセンターでも、コストエンジニアリングとキャパシティプランニングは必然的にトイルと結びついている
- 将来的に必要となるリソースについて、コスパの良いベースラインやバースト時のリソースを確保すること
- 発注書, AWSのRI, クラウドベンダーとの値下げ交渉契約として解釈されることもあり
- 製品のローンチや祝日のように、重要な高トラフィックのイベントへの準備(と後始末)
- 上流や下流へのサービスレベル・上限の確認
- 異なる性能構成に対するワークロードの最適化
- 大きなサーバー1つ or 小さなサーバー4つ
- クラウドサービス独自のシステムの課金に対する最適化
- AWS DynamoDB, GCP Datastore
- 安い「スポットインスタンス」や「プリエンプティブVM」をより有効に使うためのツールのリファクタリング
- 上流のインフラや、下流の顧客のどちらかで超過したリソースへの対応
- 将来的に必要となるリソースについて、コスパの良いベースラインやバースト時のリソースを確保すること
- 分散マイクロサービスが一般的になってきたが、分散するにつれて新しい障害が発生してくる
- 洗練された分散型トレース、高品質なモニタリングシステム、詳細なダッシュボードがない場合もある
- ツールがあっても全てのシステムで動作していない可能性もある
- トラブルシューティングでは個々のシステムにログインし、アドホックなログ分析クエリのスクリプトを書く必要があるかもしれない
- トラブルシューティング自体は悪ではない
- 不安的なシステムアーキテクチャによる不具合に毎週対処するのではなく、新しい障害にエネルギーを向けるべき
- 99.99%の可用性を持つサービス
- 10個のサービスが組み合わさると、99.9%の可能性(0.9999^10)になってしまう
- 洗練された分散型トレース、高品質なモニタリングシステム、詳細なダッシュボードがない場合もある
- どの規模の本番システムでも、トイル管理はとても重要
- トイルを特定・定量化したら、それを除去するプランが必要になる
- 数週間、数ヶ月かかる可能性がある
- 強固で包括的な戦略を持つことが重要
- トイルを特定・定量化したら、それを除去するプランが必要になる
- トイルを根本から除去するのが最適な解決策だが、出来ない場合は他の方法が必要になる
- ここでは2つのケーススタディの前に、トイル削減のプランニングをする際の一般的な戦略について記述
- トイルのニュアンスはチームや企業によって異なる
- しかし、どのような組織においてもいくつかの戦術は共通している
- 以下の各パターンは、後のケーススタディ内で少なくとも1つは具体例あり
- データ駆動のアプローチを採用することを推奨
- トイルの発生源を特定・比較する
- 客観的な修正の決定を行う
- トイル削減プロジェクトよって削減できた時間 (ROI) の定量化
- 自分のチームがトイルによる疲弊を経験している場合は、トイル削減を自身のプロジェクトとして扱う
- GoogleのSREチームはバグによるトイルをトラッキングし、トイルをランク付けしている
- トイルの修正かかる時間と、修正によって削減される時間によるランク付け
- GoogleのSREチームはバグによるトイルをトラッキングし、トイルをランク付けしている
- テクニックと説明についてはP96のトイルの計測を参照
- 元から対処するのがトイルに対する最適な戦略
- 既存システムやプロセスによって発生しているトイルを管理する労力を費やす前に、システム変更によってトイルが削減・除去できないか調べる
- 本番環境でシステムを運用しているチームは、そのシステムの運用について貴重な経験を持っている
- SREチームは開発チームと協力して、この知識を開発に活かすべき
- 低トイル、スケーラビリティ、セキュリティ、自動復元
- SREチームは開発チームと協力して、この知識を開発に活かすべき
- トイルに疲弊したチーム
- 時間の使い方やエンジニアリングについてデータに基づく決定をすべき
- 経験上、トイル中心のタスクを拒否することは一番最初に考える選択肢
- 一見、非生産的に見える
- 一連のトイルにおいて、トイルに対処する場合としない場合のコストを分析する
- もう一つの方法は、意図的にトイルを遅らせる
- バッチ処理や並列処理向けに蓄積する
- トイルを大きな塊として扱うことで、差し込みをい減らしトイルのパターンを特定するのに役立つ
- サービスには明文化されたSLOを定義すべき
- 第2章にて説明
- SLOに基づいて意思決定ができるようになる
- 例: エラーバジェットを消費・超過しない限り、オペレーションタスクをしない
- 個々のデバイスではなく、サービス全体の状態に重点を置くSLOは、サービス成長に対しても柔軟性が高く維持しやすい
- 部分的な自動化を検討する
- 複雑なビジネス上の問題があり、多くのエッジケースや要求がある場合
- 完全な自動化の前の暫定処置
- いくつかの作業はエンジニアが行う
- たとえ手作業が残っていても、このアプローチによって完全自動化に向けて徐々に移行することが可能
- このデータをより統一的に集めるためには顧客の入力を使う(?)
- 自由な形式のリクエストを減らすことで、全てのリクエストをプログラム上で処理することに近づく
- (必要な情報を持っている)顧客との間で行ったり来たりするのを防ぐことができる
- ビックバン方式によるオーバーエンジニアリングを防ぐことができる
- ユーザーのセルフサービスによる方法を提供する
- 型インターフェース(前項の「部分的自動化インターフェースから始める」を参照)によってサービス提供を定義した後、移行する
- Webフォーム、バイナリ、スクリプト、API、またはサービス設定ファイルへのPull Requestのやり方を記載した単なるドキュメント
- 例: 新しい仮想マシンを作成するチケットをエンジニアに依頼するのではなく、プロビジョニングをトリガーするようなWebフォームやスクリプト
- もしエラーが発生した場合はスクリプトからチケットへと戻す
- 「部分的自動化インターフェース」はトイル対応の開始には良いが、サービスオーナーはセルフサービス方式を提供することを常に目指すべき
- トイル削減プロジェクト
- 短期的には機能開発やパフォーマンス改善、他の運用タスクに割けるメンバーを減らしてしまう
- トイル削減に成功すれば、長期的にはチームは健康で幸せになるし、サービス改善に多くの時間を使うことができる
- マネージャーのサポートは、メンバーを確保する上でとても重要
- トイルに対する客観的な指標で用いて、機能開発ではなくトイルに割くためのメンバーを確保する
- トイル削減を、ビジネス目標や機能と結びつけるようにする
- 例: セキュリティ、スケーラビリティ、安定性などが顧客に求められている場合、現在のトイルだらけのシステムではなく新しい低トイルシステムを望むかもしれない
- 新システムの副作用としてトイルが削減される
- 例: セキュリティ、スケーラビリティ、安定性などが顧客に求められている場合、現在のトイルだらけのシステムではなく新しい低トイルシステムを望むかもしれない
- 最初からトイルの無い完璧なシステムを設計しようとしないようにする
- 優先度の高いものだけを最初に自動化し、後で時間があるときに改善していくようにする
- MTTR(平均復旧時間)のような分かりやすい指標を用いて、改善を計測するようにする
- サービス規模が拡大すると、様々な本番サービスが増え管理しづらくなる
- 特別なマシンの存在
- 「家畜とペット」のアプローチ
- 特別なマシン(ペット)ではなく、共通のインターフェースを備えたマシン群(家畜)を使うようにする
- 何が家畜になるかは組織のニーズや規模によって違う
- ネットワークリンク, スイッチ, マシン, ラック, クラスタ全体を交換可能なユニットとみなすのも良いかも
- 「家畜」に移行するのは初期コストが高いかもしれないが、中長期的には良い
- メンテナンス, DR, リソース消費 等の削減
- 一貫したインターフェースは柔軟性があり、スケーラブルな自動化が可能
- トラフィックの迂回や復旧, シャットダウンの実行 etc...
- Googleではツールの均一化を進めている
- 使うツールを自由に選ぶことはできる
- ただしサポート外のツールやレガシーシステムによるトイルは、自己責任で対応しなければならない
-
自動化は時間を節約できる
- しかし間違った環境下ではサービス停止を引き起こすこともある
- 安全側に倒すような守りのシステムは良いアイデア (vs 攻めのシステム)
- 自動化が管理者レベルの権限を持っている場合、守りのシステムがとても大事
- 全てのアクションが実行前にチェックされるべき
-
自動化の際には以下のプラクティスに従うことを推奨
- 例え上流からのリクエストでも、ユーザーの入力値を安全に扱う。慎重にバリデーションをする
- 人間のオペレーターが受け取る間接的なアラートと同等の安全策を構築する
- コマンドタイムアウトのように単純なものだったり、現在のシステムメトリクスや停止システム数のような洗練されたものだったり
- この場合、モニタリング, アラート, 計測システムは人間と機械の両方によって使われる
- リードオンリーの操作でも、システムのスパイクや障害を引き起こす可能性がある
- 自動化の規模に応じて、安全性のチェックの負荷は徐々に高まっていく
- 自動化の不完全な安全性チェックによる障害の影響を最小限に抑えること
- 危険な状況下においては、デフォルトでは自動ではなく人間のオペレータが行うようにします
- トイルが自動化可能な場合
- トイル対応の人間のワークフローをソフトウェアでうまく真似するように考える
- 人間のワークフローを文字通りそのまま機械のワークフローとして移したいケースは少ない
- トイル対応の人間のワークフローをソフトウェアでうまく真似するように考える
- トイル対応のプロセスを完全に文書化する
- 文書化後、手作業を分解できる要素に分解する
- 部分コンポーネントごとに実装する
- コンポーネントは他の自動化プロジェクトでも再利用できる
- 文書化後、手作業を分解できる要素に分解する
- 自動化は人間のワークフローを再精査し、シンプルにする機会を提供してくれることもある
- オープンソース・サードパーティ製ライブラリを利用・拡張するようにする
- 内製ツールですべてやる必要はない
- 開発コストが削減できる
- 全部ができなくとも、部分的な自動化を手助けできるかも
- ツールやワークフロー、自動化の利用者からのフィードバックを積極的にもらうようにする
- 利用者の、基盤システムへの理解度によって前提が異なるかもしれない
- あまり理解していない人からのフィードバックが特に重要
- アンケート、UX調査、その他どのようにツールが使われているかを確認する仕組み
- フィードバックから、将来もっと効率的な自動化ができる
- 人間の入力値は考慮すべきものの一つ
- 自動化されたタスクの効率性を計測するのも重要
- レイテンシ、エラー率、やり直し率、(全関係者の)人間が節約できた時間
- 自動化やトイル削減の前後で結果が比較できる大まかなメトリクスを見つけられるのが理想
- レガシーシステム
- SREのような役割のエンジニアのほとんどがレガシーシステムに遭遇したことがあるはず
- 問題が発生することが多い
- UX、セキュリティ、信頼性、スケーラビリティ
- ブラックボックス状態
- 大抵は動く
- ほとんどの人がどのように動いているか把握していない
- 変更コストが高いし怖い
- 儀式のような運用作業
レガシーシステムから脱却するには以下のパスに従う
-
- 回避
- リプレイスするリソースがなく、コストとリスクを鑑みるとリプレイスする価値が無い
- 代替可能な商用システムもないかもしれない
- 「回避」は技術的負債を受け入れ、SREの原則を離れ、システム管理に移ることを選択すること
-
- カプセル化 / 拡張
- レガシーシステムの抽象化API、自動化、コンフィグ管理、監視、テストのシェルを構築する
- それでもレガシーシステムは変更に対して脆弱だが、適切に不正行為を特定し、ロールバックができる
- 「回避」と同様だが、高金利の技術的負債から、低金利の技術的負債へと借り換えているようなもの
- 段階的なリプレイスのための準備となる
-
- リプレイス / リファクタリング
- レガシーシステムのリプレイスは段階的に行うのが良い
- 多くの決定事項、忍耐、コミュニケーション、ドキュメントが必要となるため
- アプローチの一つとして、レガシーシステムを抽象化する、共通インターフェースを定義する方法
- 徐々に安全にユーザーを移行するのに役立つ
- カナリアリリース、ブルーグリーンデプロイのようなリリーステクニックを用いることができる
- レガシーシステムの「仕様」は歴史的な利用方法によってのみ定義される
- 歴史的に想定される入力・出力値の本番相当のサイズのデータセットを用いて構築する
- 新しいシステムが想定される動作から逸脱していないことを確信できる
-
- 退役 / 保護管理のオーナーシップ
- 最終的には、多くの顧客や機能が他の代替へ移行します
- ビジネス上の利益を整理するために、移行せず苦労している人・モノはレガシーシステムの残留物の保護管理を引き受けたとみなすことができる
