エラーバジェットとかリスク許容の話を見たくて、いまさらO'Reilly Japan - SRE サイトリライアビリティエンジニアリングを読んだ。 Googleの人が書いたエッセイ集的な側面もあるので、Googleの事故事例とかも書かれてて面白い。

PDF版を買ってメモをしながら読めるいい感じのPDFビューアがなかったので、以前作ったmu-pdf-viewerというPDFビューアを少し改善した。

Cmd + Shift+ Cで表示しているページとそのテキストをコピーできるようにして、OneNoteにスクショを貼りながらメモを取るスタイルにした。 (ページ全体だとちょっと大きいので選択範囲だけとかにもう少し絞りたい気がする。)

1章から3章にかけてエラーバジェットの話がいろいろあった。

どのぐらいの信頼性損ねても許容されるのかの指標 = エラーバジェットを使うことで、リリース速度のバランスを取るという話面白かった。 この辺はPerformanceだったりいろんなことにも言えそう。

「19章 フロントエンドにおけるロードバランシング」で、N 台のサーバがあるときにある id のパケットに対してどのサーババランシングをするかという話。 単純に id % N でも接続先を固定できそうだけど、サーバの台数が変わると N が変わって接続先も変わってしまうという問題が出てくる。 このときに、サーバの台数 N が変わっても同じハッシュ値を生成する方法としてコンシステントハッシュ法という話がでてきた。

アルゴリズムの説明読んでもイメージがしにくかったのでAssemblyScriptを使って実装してみた。 wasmバイナリで動くコンシステントハッシュ法を実装してみたけど、AssemblyScriptとかWebAssembly自体にいろいろハマった。

「22章 カスケード障害への対応」が結構面白かった。

この中で、クライアントではExponential backoffでのリトライをしないとサーバ側が過負荷のときにサーバにリクエストが飛びまくって被害が拡大するという話がでてきた。 Exponential backoffな実装はしたことがあるけど、ライブラリ書いたことがなかったので書いてみた。

次のようにDurationがExponentialな値を返すGeneratorを作ることで、Async/Awaitと組み合わせてExponential backoffなリトライができるデザインにしてみた。

import { generateBackoff } from "exponential-backoff-generator";
const doAsyncTask = async () => {
    const backoff = generateBackoff();
    for (const { sleep } of backoff) {
        try {
            return await YourAsyncTaskWantToRetry();
        } catch(error) {
            await sleep(); // wait 100ms, 200ms, 400ms, 800ms ...
        }
    }
    throw new Error("YourAsyncTaskWantToRetry failed at all");
};

doAsyncTask().then(result => {
    console.log(result); // YourAsyncTaskWantToRetry resolved value
}).catch(error => {
    console.error(error); // Error: YourAsyncTaskWantToRetry failed at all
});

元ネタはRustのyoshuawuyts/exponential-backoff: Exponential backoff generator with jitter.

「26章 データの完全性:What You Read Is What You Wrote」のデータの完全性とはなにかという話が良かった

リストアのためのバックアップであって逆ではないよという話が面白かった。 この完全性の話は「22章 カスケード障害への対応」と比べながら読むといいのかなと思った。

あとこの章はGoogleで実際におきたデータを削除する障害から復帰までの話とかがあってよかった。

第Ⅲ部 実践は全体的に読み物として面白い話が多くてよかった。

その他

  • モニタリングシステムは次の2つを答えるものになってないといけない
    • 何が壊れたのか(症状)
    • なぜそれが壊れたか(原因)
  • ポストモーテムはどの部分を改善できるかを提案する
  • 継続的なリカバリ検証
    • 運用の一部として継続的にリカバリプロセスのテストをする