「マンガが快適に読める」を数値化し、SLOをマンガビューワに導入するまで

株式会社はてなのマンガチームでSREをしているhappy_siroです。 私がチームで担当しているサービスは、いくつかのWebマンガサイトで採用されている「GigaViewer」というマンガビューワです。

GigaViewerチームでは、サービスのSLOを策定しました。 理由は、SLOに基づいて開発速度と信頼性のバランスをとるためです。

この記事では、私がチームメンバーと協力して「GigaViewer」にSLOを導入するまでのストーリーを紹介します。 はじめにSLOについて説明し、次にSLOをどのように決定したか、最後にサービスの運用でSLOをどのように活用していくかを述べます。

マンガビューワにおけるサービスレベルとは

SLOは、Service Level Objectiveの頭文字をとった用語です。 すごく簡単に説明すると、日本語でサービスレベル目標のことです。

サービスレベルとは、サービスにとって特に重要な振る舞いのことです。 マンガビューワでは、例えば「マンガが読める」ことや「マンガが快適に読める」ことが重要な振る舞いに当たるでしょう。

「マンガが読める」や「マンガが快適に読める」を目標にするには、具体的な数値にする必要があります。 この数値のことをSLI(Service Level Indicator)と呼びます。日本語では、サービスレベル指標です。

SLOとは、SLIに対する目標値のことです。 サービスが有用だという前提に立ったとき、ユーザーが満足する値にSLOを設定します。 SLOが達成されていれば、ユーザーは快適にサービスを利用しています。

SLOが未達なら、ユーザーは快適に利用できていないので、改善が必要です。 そして、SLOを基準として「サービスレベルの改善と、機能開発のどちらを優先するか?」を判断することで、信頼性と開発速度のバランスをとります。

なぜSLOを策定したかったのか

私は、SLOによる運用をできる限り早く開始したいと考えていました。SLOはSREの仕事の基礎になる数値です。 というのも、SREとして仕事をするためには、サービスの信頼性について知る必要があるからです。

サービスの信頼性がわかっていれば、このサービスは信頼性が不十分なので改善しよう、このサービスは十分なのでほかを対処しようと判断できます。 どこに手を入れるべきかを判断するには、SLOを決定することが重要です。

サービスレベルを単純に決める

SLOを決めるため、まず最初にサービスレベルを決定します。 早くSLOを運用に利用したいので、あえて単純に決めました。下記の2つです。

  • マンガが読める
  • マンガが快適に読める

この抽象的な2つのサービスレベルを、具体的に計測できるSLIにする必要があります。

何をサービスレベル指標としてどう計測するか

それではSLIを決定します。 「マンガが読める」が達成されているかを計測するには、サービスの可用性を計ると良さそうです。

同様に「マンガが快適に読める」が達成されているかを計測するため、サービスのレイテンシーを計ります。

一般的なSLIの表現

SLIは、ある期間の中の全てのイベントと正常なイベントの比(%)で表現します。 数式で表すと、下記のようになります。

SLI = (期間内の正常なイベント ÷ 期間内の全てのイベント) × 100

このように表現すると、サービスレベルがどのくらい良いのかが直感的に把握できます。0%なら何も動いていないということですし、100%なら完璧です。

なお、パーセントで表現することは、SREを実践するエンジニアのためにGoogleが公開している『The Site Reliability Workbook』のChapter 2を参考にしました。次で説明する集計期間を移動することも同様です。

サイトリライアビリティワークブック ―SREの実践方法

サイトリライアビリティワークブック ―SREの実践方法

  • 発売日: 2020/06/15
  • メディア: 単行本(ソフトカバー)

期間を移動しながら集計する

SLIはある期間で集計しますが、その期間は移動平均のように移動します。

例えば、集計を1月1日に開始して、期間は1ヶ月だとします。 1月1日には、12月1日から1月1日までを集計します。1月2日には、12月2日から1月2日までを集計します。 このように集計するのは、ユーザーが障害をすぐには忘れてくれないからです。

このような集計をしなかったケースを考えましょう。 1月は、1月1日から1月31日までを集計期間とします。 1月31日に障害が発生しました。2月1日から新しい集計期間が始まるので、1月31日のことは忘れられます。

ユーザーが、こんなにきっぱりと障害を忘れてくれることはありません。 集計期間をスライドすることで、SLIに対する障害の影響が徐々に薄まるようにしています。

アクセスログからサーバーのSLIを計測する

SLIを計測するデータには、HTTPサーバーのアクセスログと、PageSpeed Insights APIの結果を用います。

アクセスログはfluentdAmazon S3に転送され、Amazon Athenaを利用してRedashからクエリすることで計測と可視化を実現します。 ここでは、サーバーのSLIとして可用性とレイテンシーを計測できます。

可用性は下記のように計測します。

(28日間でServerErrorでないリクエスト ÷ 28日間の全てのリクエスト) × 100

また、同じようにレイテンシーを、ある値以下であるリクエストを正常なイベントとして、下記のように計測します。

(28日間でレイテンシーがある値以下のリクエスト ÷ 28日間の全てのリクエスト) × 100

ともに集計期間を28日間(ちょうど4週間)としたのは、私たちのサービスは曜日によるアクセスの変動が大きく、どの期間でも同じ数の曜日を含むようにするためです。

PageSpeed Insights APIでフロントエンドを計測

上記のほか「マンガが快適に読める」のSLIを、より詳細にフロントエンドの性能で計測しています。 フロントエンドのSLIも、ある期間の中の正常なイベントと全てのイベントの比で表します。

PageSpeed Insight APIを利用し、取得できるメトリクスがある値以下であるリクエストを正常とします。 PageSpeed Insights APIはAWS Lambdaで呼び出し、計測結果をAamzon S3に保存して、上記と同じくRedashとAthenaで計測・可視化しています。

最後に、フロントエンドの「マンガが読める」のSLIは、現状で計測できていません。 SLOの運用をできるだけ早く開始したかったため、相対的に実装に時間がかかりそうなフロントエンドの可用性の計測は諦めました。 ただし、フロントエンドのエラーを集計する仕組みはすでに持っているので、実装は可能だろうと考えています。

プロダクトオーナーとともにSLOを決定する

ここまでサービスレベルとSLIは、主にエンジニアが決定しました。 しかし、目標であるSLOについては、サービスの方向性を決定する権限と責任を持つ人、例えばプロダクトオーナーと一緒に決める必要があります。

なぜなら、次の点においてプロダクトオーナーが同意する必要があるからです。

  • SLOがユーザーにとって十分に良く、SLOを下回るサービスレベルは許容できない
  • 許容できないサービスレベルには、エンジニアの工数を割り当てて、改善する必要がある

もし、プロダクトオーナーがこれらに同意できていないなら、SLOに違反したとしても有効なアクションを起こすことができず、形骸化してしまいます。

決定したSLO

私もSLOを決定する際にプロダクトオーナーのレビューを受け、次のように指摘されました。

  • マンガビューワはリクエストの99.9%を、0.5秒のレイテンシで返す必要がある

たしかに、マンガを読む機能はこのサービスのコアなので、ほかよりもレイテンシを低く保つ必要がありそうです。 このSLIも追加することにしました。Athenaを利用していたので、SQLを少し書き換えるだけで実装できました。

こうしてGigaViewerのSLOが最終的に決定しました。その一部を紹介します。なお、集計期間はすべて28日間です。

可用性:

(ServerErrorでないリクエスト ÷ 全てのリクエスト) × 100 > 99.5

ビューワの性能:

(レイテンシーが0.5s以下のリクエスト ÷ 全てのリクエスト) × 100 > 99.9

その他の性能:

(レイテンシーが0.5s以下のリクエスト ÷ 全てのリクエスト) × 100 > 99.0

どのように監視するか

SLOが決まったら、どのように監視するかを検討する必要があります。

単純な方式としては、SLOを閾値として下回ったらアラートを通知することが考えられます。 しかしこの方法では、SLOに違反したときにしか対処できません。SLOに違反してユーザーが不便を感じる前に対処したいので、これでは不十分です。

私たちは、バーンレートという方法を採用しました。 バーンレートとは、次の数式でエラーバジェットを定義し、これが消費される速度を表します。

エラーバジェット = 100 − SLO

「現在のエラーレートが続いたら、どのくらいの期間でSLOに違反するのか」をもとにアラートを通知しています。 こうすることで、SLO違反が発生する前にサービスレベルの悪化を検知でき、ユーザーが不便を感じる前に対処できる可能性が上がります。

これらの監視システムは、RedashのAlertという機能を利用して実装しています。

SLOに対するアラートが上がったときの対応も、このタイミングで決定します。 私たちのチームではバーンレートを利用しているので、マネージャーへ報告した後で、対処に当たることにしました。

もちろん今まさにSLOに違反しているときは、障害ですので報告は不要です。

まとめ

SLOは、定期的に見直していくことが必要です。 次の機会では、SLOをどのように見直し変化しているか、さらにSLOを意思決定に活用している様子などを紹介できればと考えています。

以上が、私たちのチームでSLOを導入するまでのストーリーです。 具体的な値を公表することが難しいこともあり、抽象的な表現になってしまったところもありますが、参考になれば幸いです。