調査で最初にやるのは時刻を確定させることだ
一言でいうと
調査で最初にすることは、原因を探すことではなく、時刻を確定することです。開始と終了が決まって初めて影響範囲を数えられ、そうして初めて、仮説ごとに「データに何が見えるはずか」を書けます。
なぜ必要なのか
ある日、決済エラーの報告を受けて4人が集まりました。1人は「今朝のデプロイ」を、1人は「特定の顧客企業のトラフィック急増」を、1人は「データベース接続の枯渇」を挙げました。3つとももっともらしく、3つとも調査に30分ずつかかる話でした。2時間後に原因は4つ目の候補だとわかりましたが、それまで誰も事故がいつ始まったのかをデータで確認していませんでした。
開始時刻を先に確定していれば、その場で2つが消えていたはずです。デプロイは事故が始まってから40分後に出ていて、問題の顧客企業のトラフィックは、事故のあいだずっと平常どおりでした。どちらの事実も、1回の照会で出ました。順序を入れ替えるだけで、2人の30分が浮きます。
ここで重要なのは記憶ではなく記録です。人の記憶は「10時ごろからだった気がする」と言いますが、データは「エラー率が0.05を超えた最初の瞬間」を正確に語ります。調査の1行目は、いつもその条件式とその時刻でなければなりません。
どう動くのか
順序は6段階です。
1つ目、時刻を確定します。何を「事故」と見なすかの条件式を、先に固定します。たとえば「5分のウィンドウで5xx率が5%を超える」です。そのあと、レンジクエリで、その条件が最初に真になった時刻と、最後に真だった時刻を探します。このとき、絶対時刻では書きません。タイムゾーンとサマータイムが、振り返りを台無しにします。「今から何分前」と書いておけば、あとで誰の画面でも、同じ区間を描き直せます。
2つ目、範囲を数えます。何件が失敗したか、どのハンドラーがどれだけ占めたか。ここでよくある落とし穴は、ウィンドウを短く切ることです。事故の区間を不足したまま覆うと、失敗件数がまるごと抜け落ちます。条件が真だった分だけを選んで、その分の増加量を足せば、ウィンドウの長さに左右されません。
3つ目、仮説と予測を先に書きます。仮説だけを書くと、あとでデータを見て、解釈を合わせてしまいます。「この仮説が真なら、どの指標がどう見えるはずか」を先に書いておけば、データがその形でないとき、仮説を捨てられます。
4つ目、棄却します。確証よりも反証のほうが安いのです。1つのハンドラーの欠陥なら、そのハンドラーだけエラー率が跳ねるはずなのに、4つのハンドラーがすべて同じ割合で跳ねているなら、その仮説はそこで終わりです。トラフィックの急増ならリクエスト率が上がるはずなのに、事故区間のリクエスト率が直前1時間と6%しか違わないなら、その仮説も終わりです。
5つ目、残ったものを別のシグナルで確証します。棄却したあとに残った1つを、最初の条件式とは別の指標で確認します。同じ指標をもう一度見るのは、確証ではなく、同じ言葉の繰り返しです。エラー率で事故を定義したなら、確証はキューの深さや飽和度のように、エラー率と独立に動くシグナルに求めるべきで、そのシグナルが同じ区間で同じ形に動いたかを、分単位で重ねて見る必要があります。
6つ目、機械が読めるタイムラインを残します。Google SRE Bookのポストモーテム文化の章が強調するのも、「何を残すか」です。出来事ごとに、相対時刻と根拠の指標を1行ずつ残します。人が読む文章は、あとから統計にはできませんが、表なら統計にできます。
現場での姿
効果的な障害調査の章が繰り返し述べているのが、この順序です。ところが、ポストモーテムで最もよく抜け落ちる欄は、原因ではなく検知遅延です。影響が始まった時刻とアラートが鳴った時刻の差は、ほとんどいつも記録されません。ところが、この数字が、次の四半期に何を直すかを決めます。5分のウィンドウに10分の継続条件をかけていると、検知に11分かかり、事故が20分のものだったなら、半分が過ぎてから人が起きたことになります。
もう1つは、無関係な出来事を同じタイムラインに載せることです。同じ12時間の中に、テールレイテンシだけが跳ねる区間が別にあり、エラーの事故と時間が重なっていないのに、振り返りの文書に一緒に書かれることがあります。タイムラインに載せるときは、各行に根拠の指標を一緒に書いておかないと、あとで2つが別の出来事だったことが残りません。
3つ目は、仮説の数を増やす方向に会議が流れることです。候補が6つになると、人が6方向に散らばり、それぞれ別の指標を開いて、異なる時間軸を見ます。調査で必要なのは、候補を増やす能力ではなく、安く棄却する順序です。予測が最も具体的な仮説から確認すれば、1回の照会に1つずつ脱落していき、残る候補が2つ以下になれば、そこからは複数人でかかっても重なりません。棄却に使ったクエリとその結果をそのまま貼っておくことは、あとから来る人にとって、結論よりも価値があります。
最後は、調査の過程そのものを残さないことです。棄却した仮説と棄却した根拠を書いておかないと、次の事故で同じ仮説にまた30分を使います。棄却の記録は、原因の記録と同じだけの価値があります。
次のラボですること
PodのPrometheusの12時間分に入っている1回の事故を、順序に沿って調査します。条件式を固定して、開始と終了を相対時刻で確定し、条件が真だった分だけを選んで、失敗件数とハンドラーごとの分布を数えます。仮説3つと、各仮説の予測を先に書いたあと、照会で2つを棄却し、残った1つを別の指標で確証します。そのあと、機械が読めるタイムラインとポストモーテムの資料を作り、最後に今より早く捉える検知ルールを書いて、どれだけ早くなるか、その代わりに空振りのページが生まれないかを、同じ12時間のデータで検証します。