はじめに

過去、監視の領域について体系的に学んだことがなく、都度調べたり見知った知識の中で扱っているなという実感がありました。そこである程度の基礎を体系的に学ぶため、積読と化していた『入門監視』を読んだので、読書メモをまとめます。

いざ読んでみたら、さほど文量もなく読みやすかったです。

第 Ⅰ 部では監視の原則について、第 Ⅱ 部では監視の戦略について纏まっています。実践的な内容をインプットするというより、基礎知識を整理する気持ちでいたので、監視の原則については手厚めに、戦略については軽くメモに残しています。

監視の原則

本書第 Ⅰ 部のテーマである、監視の原則についてです。

まず『監視』とは。本書途中で記述ある一文がとても分かりやすかったです。

監視とは、あるシステムやそのシステムのコンポーネントの振る舞いや出力を観察しチェックし続ける行為である。

メトリクスとログ

以降、高頻度で登場するメトリクス、ログについて簡単に整理します。

  • メトリクス
    • 定期的にグループ化または収集された測定値の集合
    • 主に本書で扱われる種類
      • カウンタ(Counter)
        • 増加していくメトリクス(車の走行距離計みたいなイメージ)
        • Web サイトに訪れた累計人数を数えるといった用途に最適
      • ゲージ(Gauge)
        • ある時点の値を表す(車の速度計みたいなイメージ)
        • 過去の値について何の情報も与えてくれず、未来の値を推測するヒントもくれないことが弱点
        • 時系列データベース(TSDB)に保存することで、過去のデータを取り出したり、可視化できる
  • ログ
    • システムが生成する単なるテキスト行
    • 主な形式
      • 非構造化ログ
        • 各フィールドに明確な意味のマッピングがないログ形式
        • 人間が読むだけに利用するものなら、必要以上の複雑性はなく最適
      • 構造化ログ
        • キーと値のペアの集合でログエントリを表現し、各フィールドの意味が明確なログ形式(多くの場合 JSON)
        • 機械的な情報の抽出が容易

監視のアンチパターン

冒頭の引用に、『アンチパターン』とは何かという問に対する端的な答えがあります。

アンチパターンとは、一見よいアイディアだが実装すると手痛いしっぺ返しを食らうものをいう。 Jim Coplien

これを踏まえた上で、監視におけるアンチパターンについてです。役割として監視に挑むこと、監視している感を出すための監視は気を抜くと頭から抜け落ちてしまいそうな点であるなと気づきがありました。

  • アンチパターン 1:ツール依存
    • 監視は単純で単一の問題ではなく、非常に大きな問題の塊
      • サーバーの監視だけしても多くのものを対象にメトリクス、ログの扱いを考える必要がある
    • ツールを増やすことは恐れない
      • いくつから “多い” とするかといった定量的なものはない
      • 目的に合わせた最小の数に絞られるなら OK
      • 心配するべきは連携して使えないツールの増加
    • 既存のツールがなければ作ることも
      • ツール駆動ではなく、ミッション駆動なチームであればこそ出てくる選択肢
      • ツールの制限に囚われずに要求を満たすために必要なものを見つめたい
    • 「一目で分かる」は迷信
      • 状態を見るための 1 つの場所が欲しい
      • 1 つのツール、1 つのダッシュボードとは限らない
      • 複雑なものを 1 つに詰め込もうとして失敗することもある
    • ツールに依存しても監視の仕組みは改善されない
  • アンチパターン 2:役割としての監視
    • 監視は役割ではなくスキル
    • チーム内の全員がある程度のレベルになっておき、全員が監視に対する責任を持つ
    • 監視は他の取り組みから独立したものではなく、サービスのパフォーマンスのために重要
  • アンチパターン 3:チェックボックス監視
    • チェックボックス監視は「これを監視しています」と言うための監視システムを指す
    • このパターンは 2 のパターンと一緒に見つかることが多い
    • このパターンに当てはまってしまっているかは、以下の兆候を確認する
      • システム負荷、CPU 使用率、メモリ使用率などのメトリクスは記録しているがシステムがダウンしたことの理由はわからない
      • 誤検知が多いのでアラートを無視している
      • 各メトリクス 5 分あるいはそれより長い間隔で監視している
      • メトリクスの履歴を保存していない
    • このパターンを改善していくには次の方法がある
      • 監視しているものは何かを理解し、「動いている」とはどういう状態なのかを明確にする
        • サービスやアプリケーションのオーナーに聞いてみることから始める
      • アラートに関しては OS のメトリクスはあまり意味がない
        • 役に立たないわけではないが、オンコールの担当者に対応を迫るものではない
        • OS のメトリクスは診断やパフォーマンスの分析にとっては重要
      • 高頻度でメトリクスを取得する
        • 最低でも 60s に 1 回
        • トラフィックの多いシステムならもっと高頻度に取得する(30s、10s)
        • 取得したメトリクスの保存は高価、かつ長期間の保持は不要なことが多いため適切な間引き設定を実施する
  • アンチパターン 4:監視を支えにする
    • 監視は問題を通知することに長けている
    • 監視を増やしてもシステムが直るわけではないため、通知を受けたら問題の修正は忘れてはならない
    • 何かが壊れたらそれに対して監視を追加するのではなく、本質的な改善に努める
  • アンチパターン 5:手動設定
    • 自動化しましょう

監視のデザインパターン

アンチパターンを避けること、解決の指針が見えたら次は良しとされるパターンについて。デザインパターン 1、2 の観点は特に忘れないようにしたいです。監視可能なアーキテクチャを最初から描く重要性を再認識しました。

  • デザインパターン 1:組み合わせ可能な監視(composable monitoring)
    • 専門家されたツールを複数使い、疎結合させ監視プラットフォームを作る(Unix 哲学の実践)
    • この柔軟性を手に入れるのはアーキテクチャの複雑性を招くが、得られる利益がコストを上回る
    • 監視システムを構成する要素は後述
  • デザインパターン 2:ユーザ視点での監視
    • できるだけユーザに近いところから監視を始める
      • ユーザが気にするのはアプリケーションが動いているかどうか
    • まず監視を追加すべきなのは、ユーザがアプリケーションとやり取りをするところ
      • 監視対象を広げていくなかでも「このメトリクスはユーザへの影響をどう教えてくれるか」を意識する
    • 効果的な監視ができる初歩的なステップ
      • 1、HTTP レスポンスコード(特に 5xx
      • 2、レイテンシ
    • ↑ は何が問題なのかは示さないが、何かが問題で、それがユーザに影響を与えていることはわかる
  • デザインパターン 3:作るのではなく買う
    • 監視の仕組みが十分に成熟していないなら、いきなり自作の監視プラットフォーム構築は避ける
    • SaaS として提供されるようなものを使う(著者の考えとしては 5 年間くらいは悩まなくて良い)
    • SaaS を利用するべき理由 ↓
      • 安い(運用コスト、人的コスト、機会損失など)
      • 監視ツールの専門家ではない(多くの場合)
      • 監視をはじめるための速度(開発すべきプロダクトへフォーカスしやすい)
    • SaaS を避ける合理的な理由 ↓
      • SaaS 監視サービスでは間違いなく足りない場合(稀なケース)
      • セキュリティ、コンプライアンス上の理由
  • デザインパターン 4:継続的改善
    • GAFA、Netflix などは監視について素晴らしい取り組みをしている
    • しかしそれは 1 週間などの短期で叶うものではなく、数ヶ月〜数年間にわたる継続した注意深さと改善から生まれている
    • 常に改善し続けましょう

監視サービスのコンポーネント

デザインパターン 1 で触れられた、監視サービスを構成するコンポーネントについて。

  • データ収集
    • プル型、プッシュ型の 2 つがある
    • プル型
      • 中央サービスがリモートノードに対してノードの情報を送るよう要求する
      • 中央サービスはいつリクエストが起きるかをスケジュールすることに責任を持つ
      • スケールしづらい、という欠点を持つ
    • プッシュ型
      • クライアント(サーバ、アプリケーション)がデータを所定の場所に一定間隔 or イベント発生時に送信する
      • 送り先だけ知っていれば受信側がどう実装されているかは知る必要がない
      • ポーリングを行う中央サービスは存在しないためスケールしやすい
        • 分散アーキテクチャでも冗長性に優れ、高可用性のある構成がとりやすい
  • データストレージ
    • メトリクス
      • 時系列データであるメトリクスは、通常時系列データベース(TSDB、Time Series Database)に保存される
        • TSDB は、基本的にはタイムスタンプをキーにした値のペアから構成される時系列データを保存するためにデザインされたデータベース
      • キーと値のペアをデータポイントと呼ぶ
    • ログ
      • シンプルな方法:通常のファイルにデータを保存する
      • 高度な方法:検索エンジン、例えば Elasticsearch にデータを保存する
        • ロギングプラットフォームの多くは検索を透過的に行える
  • 可視化
    • 時系列データの最も一般的な可視化の方法は、折れ線グラフ(ほとんどの場合これで足りる)
    • 円グラフは使わない
      • ある時点でのデータを全体との関連で表現できるが、ほとんどの場合で棒グラフの方が良い選択肢になる
      • 円グラフには過程やトレンドといった情報を含まないため
    • 最高のダッシュボードとは
      • 1 つのサービス、プロダクトのステータスを表示することに焦点を絞るもの
      • サービス、プロダクトをよく理解したメンバーによって構築、運用されているのが理想
  • 分析とレポート
    • 監視データの種類によって、可視化から分析とレポートまで踏み込むことで有益な場合がある
    • SLA の決定とレポートを行う場合など
  • アラート
    • 監視はアラート出すために存在するものではない
    • アラートは結果の 1 つの形でしかない
    • 「監視は、質問を投げかけるためにある。」Dave Josephsen, Monitorama 2016

アラート

「監視はアラートを出すために存在するものではない」とあるが、具体的にどのようなものか。アラートの使い道、さらにそこからアラートを改善するためのステップは実践的で参考になりました。

  • アラートの意義
    • アラートを受け取った人に対して、緊急性がありすぐに対応することを認識させる
    • それ以外の情報はおよそ以下として扱う
      • ログ
      • 社内のチャットルームへメッセージ
      • チケットの自動生成
  • アラートの使い道と扱い
    • すぐに応答かアクションが必要なアラート
      • PagerDuty などを通じて通知
    • 注意が必要だがすぐにアクションが必要ないアラート
      • 社内のチャットルームへメッセージ
      • 他でも良いが、後日レビューが可能なような場所へ
    • 履歴や診断のために保存しておくアラート
      • ログとして残す
  • アラートをログとして残す重要性
    • アプリケーションやサービスのどの部分でトラブルが多く、どこに改善の焦点を当てればよいのか把握できる
  • アラートの難しさ
    • システムのメトリクスは急激に変化しやすい
      • そのままデータポイントを使ってアラートを送ると誤報に繋がる
      • 移動平均を使ってデータをならすことで対応する
      • しかし、これにより情報の粒度が落ち、重要なイベントを見逃すことがある
    • 人間が持つ注意力の限界
      • アラートを受け取った人間の注意力はアラートを受け取るたびに削られていく
      • 本来持つ注意力は、監視システムに対してではなく選んだ問題に対して使いたいはず
  • アラートの改善
    • アラートにメールを使うことを避ける
      • メールは誰かを叩き起こすためのものでなければ、そのために使おうとするものではない
      • 使いみちに示した、使いみちに応じた適切な場所へ通知する
    • 手順書を書く
      • 手順書はアラートがきたときに、すばやく対応方針を示す手段に最適
      • 各アラートには対象サービスの手順書へのリンクを入れておく
      • 良い手順書は以下の質問に答えられるもの
        • これは何のサービスで、何をするものか
        • 誰が責任者か
        • どんな依存性を持っているか
        • インフラの構成はどのようなものか
        • どんなメトリクス、ログを送っていて、それらはどういう意味なのか
        • どんなアラートが設定されていて、その理由は何なのか
    • 固定の閾値を決めることだけじゃない
      • 適宜、変化量やグラフの傾きを利用する
    • アラートを削除しチューニングする
      • うるさすぎるアラートは割れ窓や、アラート疲れに繋がる
      • 簡単ではないが、アラートの量を減らす
      • アラートの量を減らすには次のような次の問を行ってみる
        • このアラートは誰かがアクションする必要がある状態か
        • 1 ヶ月間のアラート履歴をみた上で削除、変更できないか
          • どんなアクションをとった?
          • 各アラートの影響はどうだった?
          • 監視の内容を正確にできる?
        • アラートを削除するために自動化できることがあるか
    • メンテナンス期間を使う
      • アラート送られることがわかる作業がある場合は、一時的にアラート通知をメンテナンス状態にしておく
    • 自動復旧を試みる
      • アラートに対するアクションが、既知で用意された手順書に従うだけなら自動化を検討する
      • 様々な実装方法があるが、簡単なのは復旧手順をコードで実装し、監視システムにそれを実行させること
      • 自動復旧によって解決できない問題はアラートを送る

オンコール

緊急性の高いアラートをどう扱うか。実務においてチームへ適用可能な部分、参考になる部分が多かったです。

  • オンコールとは
    • 何か問題が起きたという呼び出しに答えられるようにしている担当のこと
  • 不要な対応に迫られることを避けるためにできること
    • 誤報を修正する
      • 100% 正確なアラートは難しくても、それに向かってチューニングをしていく
      • オンコール担当は役割の 1 つとして、前日に送られたすべてのアラートリストを作る
      • 各アラートがどのように改善できるか、または削除できるかの観点で見直す
    • 場当たり的な対応を減らす
      • 前述したとおり監視自体が問題を解決するものではない
      • システムの改善へ繋げるためにとれる手法
        • 1、オンコールシフト中、システムの回復力や安定性に対して取り組むことを役割にする
        • 2、前週のオンコールの際に収集した情報を元に、次週チームへ展開する
    • オンコールローテーションを上手く組む
      • ローテーションの決まったスケジュールルールがなければ、次のルールで運用してみる
        • 4 人チームいるとして
        • 各人が 1 週間ずつ、水曜午前 10 時に始まり 1 週間後に終える
        • この 4 週単位のローテーションを組んでみる
      • カレンダーの週に合わせるのではなく、出勤日にローテーションを始める点が重要
      • 出勤日に切り替わりがあることで、チーム内でオンコールの引き継ぎが容易になる
        • 注意点、気づいたことの議論が行いやすい
  • プライマリのオンコール担当に、バックアップ担当は必要か否か
    • ほとんどの場合で不要
      • セカンダリの担当も、プライマリと同じ体制が求められるしバーンアウトにも繋がる
    • 一人きりにするという意味ではなく、エスカレーションパスは整備する
  • プライマリのオンコール担当が、アラートに応答できなかった場合
    • 1 度きりなら、応答できなくても許容すべき
    • ただ、オンコール担当がアラートに応答しないことが続くなら、何か別の問題がある
  • オンコールに対する補償も検討する
    • オンコールシフトの直後に有給休暇を 1 日取らせる
    • オンコールシフトごとに手当を支給する

インシデント管理

インシデント管理について、ITIL をシンプルにしたおすすめのプロセスは、組織に存在しない状態であればすぐにでも実践できるようなものだと感じました。

  • インシデント管理とは
  • ITIL をシンプルにしたプロセス
    • 1、インシデントの認識(監視が問題を認識)
    • 2、インシデントの記録(インシデントに対して監視の仕組みが自動でチケットを作成)
    • 3、インシデントの診断、分類、解決、クローズ(オンコール担当がトラブルシュートし、問題を修正し、チケットにコメントや情報を添えて解決済とする)
    • 4、必要に応じて問題発生中にコミュニケーションを取る
    • 5、インシデント解決後、回復力を高めるための改善策を考える
  • インシデント管理における役割
    • 現場指揮官(IC、incident commander)
      • サービス停止に関する調査を監督するのが役割
    • スクライブ(scribe)
      • 起こったことを記録しておくことが役割
      • 誰が何をいつ行ったのか、どんな決断がされたのか、どんなフォローアップすべき事項が見つかったのかを記録する
      • 調査や改善は行わない
    • コミュニケーション調整役(communication liaison)
      • 社内外問わず利害関係者に最新状況のコミュニケーションをとることが役割
      • インシデント対応する人、何が起きているの知りたい人との唯一のコミュニケーションポイントとなる
      • 利害関係者がインシデントの解決に取り組んでいるメンバーに直接状況を聞き、解決を妨げないことも重要
    • SME(subject matter expert)
      • 実際にインシデント対応することが役割
  • 役割の決め方におけるアンチパターン
    • 通常時の上下関係をそのままインシデント対応に適用する
      • チームマネージャが IC になるなど
      • チームマネージャがコミュニケーション調整役、エンジニアを IC にするほうがおすすめ
  • インシデント解決後はポストモーテムを実施する
    • 原則的に、利害関係のある全ての組織から人を集め、何が問題で、なぜ発生して、再発防止のためにチームでどう対応していくのかを議論する

統計入門

  • モダンな監視スタックの重要な原則の 1 つが、監視サービスが送ったメトリクスを破棄しないこと
    • データを保存しておくことで、統計を使った問題の発見に役立てられる可能性を広げる
    • 過去に対する多くの情報を得ずに、未来を洞察、推測できない
  • ほんのさわり、基礎中の基礎だけ
    • 平均(mean / average)
      • 集合内の個別の値を確認することなく、その集合がどのようなものなのかを表すのに便利な値
      • 時系列データにおける平均のよくある使い方の 1 つは、移動平均
        • スパイクの多いグラフを平滑化する効果があったり
        • TSDB においてデータを間引きしたり
      • 平滑化を行うと、正確さを犠牲にした上で見え方が向上する
    • 中央値(median)
      • データセットの真ん中
      • 一方向に大きな偏りあるデータセットを扱うとき、平均よりも中央値の方がデータセットの特性をよく表す場合もある
    • 周期性(seasonality)
      • データポイントがパターンを繰り返すこと
      • 周期性の高い負荷に対しては、将来どのようになるかが推測できる
        • これはサービス、アプリケーションによってあったりなかったりする
    • 分位数(quantile)
      • データセットのある点を表す統計的手法
      • 最もよく使われる分位数はパーセンタイル
        • パーセンテージ(0-100)でデータセット内の点を表現する方法
      • パーセンタイルは、帯域幅に対する課金、レイテンシのレポートによく使われる
      • パーセンタイルは平均できない
        • 計算の性質上、ある程度のデータは捨ててしまうため
    • 標準偏差(standard deviation)
      • 監視の領域で扱うことはあまりない
  • データを考える上で考慮すべき問
    • どちらか一方に大きな偏りがあるデータ?データポイントはの集まりはどちらかのは端にあるか?
    • 極端な外れ値がよく発生するか?
    • データポイントに上限あるいは下限はあるか?
      • レイテンシは正の方向に対して無限に値を取り得る
      • CPU 使用率は上限も下限もある

監視戦略

本書第 Ⅱ 部のテーマである監視戦略について。普段 Web サービスの開発をしている観点から、個人的に気になったところだけメモとして残しています。本書ではより広範な領域を扱っているため、気になる方はぜひ実際に読んでいただけるとよいかと思います。

ビジネスを監視する

ビジネスに対して、監視という技術領域をどう活かすかについて。サービスを利用するユーザ、サービスを提供する経営層も同じくサービスが使えているか、は大きな関心ごとの一つ。

  • 経営層がするような質問ができるようになると、重要で大きくレバレッジが効いた、ビジネスに直結する問題に取り組める
  • 経営層の視点からの関心
    • 顧客はアプリケーションあるいはサービスを使えているか
    • 儲かっているか
    • 成長しているか、縮小しているか、停滞しているか
    • どのくらい利益が出ているか。収益性は改善しているか、悪化しているか、停滞しているか
    • 顧客は喜んでいるか
  • NPS、LTV、CAC など一般的なビジネス KPI は抑えよう
    • 本書ではいくつか例示がある
  • アプリケーションにメトリクスがない場合
    • アプリケーションやインフラのパフォーマンスに対する可視性を上げるにはデザインが必要
    • 必要な計測データをアプリケーションが出していないなら、アプリケーションに変更を加えよう
  • 会社のビジネス KPI を見つける
    • どのようにアプリケーションが動いていて、何を計測するのが重要か、人と話すことが間違いない
      • まずはプロダクトマネージャ
        • 何が問題なのかを高いレベルで把握していることが多いため
      • ソフトウェアエンジニアリングチームのマネージャ
      • シニアソフトウェアエンジニア
    • たとえ短時間でもエンジニアリング分野でない人と話すをすることで、エンジニアリングの考えから抜け出すことができる
      • ある種のマインドハック
      • エンジニアリング分野外の視点を理解するのは常に重要なこと
    • 別の方法としては、アプリケーションの機能について概略図を描いてみることがある
      • まずはログイン、検索、地図のロードなど、機能をマッピングしてみるのがよい

アプリケーション監視

かなり飛ばし気味で読んでしまいましたが、最低限押さえたいアプリケーションの監視について。

  • ログとメトリクスでアプリケーションを計測するのは、パフォーマンスを把握し、トラブルシューティングする能力を高めるために重要
  • ビルド、リリースパイプラインも監視対象とし、アプリケーションやインフラとの関係性を残す
  • ログ、メトリクスどちらにするべきか
    • 著者の経験則
      • 1、チームにとってメトリクスで考えるほうが楽か、ログで考える方が楽か
      • 2、その問題について、メトリクスとログのどちらがより効果的か(ユースケースによって考える)
  • 何のログを取るべきか
    • トラブルシューティングあるいは単なる仕組みの説明時に、あったら便利な情報とは何か
    • この質問を軸に、アプリケーションを考えることに時間を使っていく

サーバ監視

一言にサーバといっても様々な種類が存在するが、最低限の基礎について。

  • Web サーバ
    • パフォーマンスとトラフィックのレベルを測る上で、RPS を追うのがベター
    • パフォーマンスにはそこまで致命的ではないが、全体感を掴む上では HTTP ステータスコードを監視する
  • データベースサーバ
    • トラフィックレベルを測るには、コネクション数
    • 忙しさを測るには、秒間クエリ数
  • ロードバランサ
    • フロントエンド、バックエンド共にメトリクスを取る
    • どちらも同じメトリクスの集合になるが、ロードバランサ自体の状態、バックエンドのサービス状態、別々の情報を知りたい
  • メッセージキュー
    • キューの長さと消費率を監視する
  • キャッシュ
    • 主に以下 2 点を監視対象とする
      • キャッシュから追い出されたアイテム数
      • ヒット・ミス比率(またはキャッシュヒット率)

監視を育てる

厳密には監視戦略の部にあったものではないですが、以下付録にあった内容から気になったところです。

  • 監視は一度作って終わりではない
  • アプリケーションコードと同様に継続的な改善を
  • 著者はそれを「監視を育てる」と形容している