📚

SRE本に登場する式 `CU = RK` を理解したい

に公開

概要

SRE 本 「17章 信頼性のためのテスト」 の 「17.1節 ソフトウェアテストの種類」にて、 カナリアテストについて記載されています。

その中に、 CU = RK という式が登場します。

書籍内では、 CU = RK を、「報告される分散の増大する累積値 CU = RK」 と表現しています。
この訳を含め、この式で説明したいことが上手く理解できなかったので、理解するために深堀りしました。

前提

この式は、カナリアテストについて説明している節で登場しています。
以降の情報も、カナリアテストについて言及している前提でお読みいただければと思います。

結論

"報告される分散の増大する累積値 CU = RK" の意味

こちらは、「報告される差異の累積数 CU = RK が増加する(と予測される...)」の翻訳ミスと思われます。

以下、 https://sre.google/sre-book/table-of-contents/ から、該当箇所の引用です。

We expect a growing cumulative number of reported variances CU = RK where ...

また、ここでいう "差異" (原文の variances ) は、ソフトウェアの期待する動作との差異...つまりは、"ユーザーの目に見える形で影響を与えるバグ" という解釈になりそうです。

CU = RK で表現したいこと

以下原文の通り、 CU および RK 共に「報告される差異の累積数」です。

We expect a growing cumulative number of reported variances CU = RK where ...

CURK もユーザーからのエラー報告数であり、もっと言うと CU = RK = ユーザーからのエラー報告数 という事です。

この式で説明したいことは、以下の通りだと読み解きました。

  • 左辺の CU は、「簡単に特定できる単純なバグ( U が小さい)ほど、ユーザーに見つかりやすい( C が大きい)」という事象を式で表現している
    • 言い換えると「隠れているバグ( U が2や3 )ほど、ユーザーに見つかりにくい(Cが小さい)」
    • そして、隠れているバグほど、発現すると急速に被害が拡大するのが常
  • 右辺の RK は、「より短時間でユーザーを新機能へ割り当てる( Kが小さい )ほど、報告は増える」という事象を式で表現している

詳細

左辺 CU の解釈

C の意味

ユーザーが認識可能な形で顕在化した差異(≒異常な振る舞い)の総数です。
ユーザーからの報告の有無が重要かは不明です。

以下、該当箇所の原文。

This strategy minimizes the total number of user-visible variances C while still allowing an early estimate of U (hoping for 1, of course).

U の意味

バグの単純さ(深刻さ?)を表現した値です。

U は 1,2,3 の値を取り、各値の解釈は以下の通りです。

  • U=1
    • リクエストが発生すると確実に再現できる、発見しやすいバグ
    • 問題を含むコードを踏むだけで、即座にエラーというフィードバックが得られる状態
  • U=2
    • あるリクエストが、将来の他のリクエストに影響を与える状態
    • 問題を含むコードを踏むと、異常なデータが生成されるだけで、エラーは発生しない
    • 異常なデータを参照する際に初めて、エラーが顕在化する状態
    • ストア型の XSS などが良い例
    • 障害の顕在化までラグがあるため、発見が遅れ、問題が拡散しやすい
  • U=3
    • 生成された異常なデータが、過去に生成したデータを参照するリクエストに影響を与える状態
    • 一例は「ID の重複を許してしまった状態」
      • 何らかのリソース作成リクエストが成功し、IDを発行
      • この時発行したIDが既存のIDと重複してしまったが、構わず保存
      • 以降、該当IDを参照する処理(新しく作成したリソースはもちろん、過去に作成した同じIDを持つリソースへのリクエストまで)が全部失敗する
    • 影響範囲が非常に広いため、 U=2 の時よりも問題コードの特定が難しい

数字が小さいほど、障害の原因が単純で発見しやすく、
数字が大きいほど、厄介な障害(障害が顕在化するまで時間がかかり、影響範囲も広く、問題を特定しにくい)ということです。

以下、該当箇所の原文。

Dividing and correcting for K gives an estimate of U, the order of the underlying fault.91 Some examples:
U=1: The user’s request encountered code that is simply broken.
U=2: This user’s request randomly damages data that a future user’s request may see.
U=3: The randomly damaged data is also a valid identifier to a previous request.

◆ 左辺 CU 全体の解釈

原文の通り、 CU = ユーザーからのエラー報告数 です。

ユーザーからのエラー報告数 が一定だとすると、 U が小さいほど C が大きくなります(逆もまた然り)。

これは、以下を意味します。

  • 単純な障害(Uが小さい)ほど、リクエストが即座に失敗するため、ユーザーがすぐに気づき報告されやすい(C が増える)
  • コードに問題は存在するのに、障害がユーザーの目に現れない(Cが小さい)ほど、障害は複雑(U が大きい)

右辺 RK の解釈

R の意味

ユーザー、またはシステムによる、単位時間当たりのエラー報告率です。
C との違いは、C はリリースから現在に至るまでユーザーが目撃したエラーの総数であり、そのうち単位時間当たりにの報告割合が R となります。

K の意味

カナリアリリースによって、新機能へのトラフィックが e倍(約172%)にまで増加する時間です。

カナリアリリースなので、新機能へ割り当てるユーザーの割合を「 1% -> 10% -> 20% -> 40% -> ...」と、段階的に増加させます。
この時の 1% -> 10% を例にとってみます。
1% -> 10% へ変更したことで、(何時間かかるか分かりませんが)最終的にトラフィックは10倍になるはずです。
その過程で、1.72倍になるタイミングがあるはずです。
この、新機能へ割り当てるユーザーの割合を増やしてから、トラフィックが1.72倍になるまでの時間をKと表現しています。

色々と書きましたが、つまり K は以下のように捉えることが出来ます。

  • K が小さい -> 短時間でe倍に -> 短い時間で、新規ユーザーへのトラフィック移行が進んでいる
  • K が大きい -> 長時間でe倍に -> 時間をかけてゆっくりと、新規ユーザーへのトラフィック移行が進んでいる

以下、該当箇所の原文。

K is the period over which the traffic grows by a factor of e, or 172%.

◆右辺 RK 全体の解釈

原文の通り、 RK = ユーザーからのエラー報告数 です。

ユーザーからのエラー報告数 が一定だとすると、 K が小さいほど R が大きくなります(逆もまた然り)。

これは、以下を意味します。

  • 短時間に多くのユーザーを新機能へ割り当てる(Kが小さい)ほど、ユーザーからのエラー報告は増える(Rが大きい)
  • 長時間に渡ってゆっくりユーザーを新機能へ割り当てる(Kが大きい)ほど、ユーザーからのエラー報告数は減る(Rが小さい)

どう役立てるの?

以下、実務で活用する例(本文を意訳した)。

  1. カナリアを少数で稼働、監視とアラートで RC の観測を開始する
  2. ロールアウトのスピード( K )は事前に設計し、監視レベルに合わせて調整する
  3. 観測値から U を推定し、U が高い兆候なら即時ロールバックや、より深い調査を行う
  4. 低次(U≈1)ならログ→回帰テスト化で原因特定と修正を進め、以後のリリースに反映する

参考文献

Discussion