blog

DeNAのエンジニアが考えていることや、担当しているサービスについて情報発信しています

2023.05.18 技術記事

ELBのCloudWatchメトリクスにより稼働率を算出する [DeNA インフラ SRE]

by Seiji Sawayanagi

#aws #alb #elb #sre #SLI #infrastructure

はじめに

こんにちは、IT 本部 IT 基盤部の沢柳です。
普段は、ライブ配信サービスをはじめとしたエンタメ領域のサービスのインフラ運用や改善を行っています。
システムの運用をしていて問題がおきたときに、どれくらいの期間と範囲かユーザへの影響を調べる必要があります。このために稼働率を使用しています。
私達のチームはおおむねAWSでシステムを構築しており、フロントにはELBを利用しています。
そこで今回はELBのCloudWatchメトリクスを用いてWebサービスの稼働率を計算する方法についてご紹介したいと思います。

Webサービスの稼働率の計算方法

稼働率とは、 システムが計測対象の時間内で正常に動作している割合 として表現されます。
Webサービスでは、一定期間内でリクエスト総数に対してAPIサーバが正常にリクエストに応答しているかで計算します。
月間稼働率であれば月内のすべてのリクエストに対して何%正常に応答しているかで表されます。

$$\mathrm{稼働率} = \frac{正常に応答したリクエスト数}{リクエスト総数}$$

正常に応答したリクエスト数とリクエスト総数に含まれるHTTPステータスのメトリクスは以下になります。
4xx番台(クライアントエラー) は、リソースに対してアクセスできない(見つからない)などの状態を表し、システム的なエラーではないためここでは正常に動作していると考えます。
5xx番台(サーバエラー)はサーバ側で問題があってエラーになっている状態を表すため、そのままエラーとして考えます。
またELB2xx番台の応答に関してはAWSのドキュメント1で確認できなかったため含めていません。

メトリクス 正常に応答したリクエスト リクエスト総数
HTTPCode_ELB_3XX_Count
HTTPCode_ELB_4XX_Count
HTTPCode_ELB_5XX_Count
HTTPCode_Target_2XX_Count
HTTPCode_Target_3XX_Count
HTTPCode_Target_4XX_Count
HTTPCode_Target_5XX_Count

上記の表から実際の稼働率は以下のようになります。 (式が長くなるためメトリクス名を省略しています。)
ELBxxxのメトリクスはELBの応答ステータス、Targetxxxのメトリクスはターゲット(APIサーバ)の応答ステータスになるので、 それぞれどのステータスもELBとTarget両方を合算する必要があります。

$$\mathrm{稼働率} = \frac{ELB3xx + ELB4xx + Target2xx + Target3xx + Target4xx}{ELB3xx + ELB4xx + ELB5xx + Target2xx + Target3xx + Target4xx + Target5xx}$$

このうち、ELB4xx,ELB5xxに含まれているステータスに関しては考慮が必要なため以下で補足します。

メトリクスについて

HTTPCode_ELB_4XX_Count

ロードバランサから送信される4xxエラーの総数になります。1
注意しておきたいのはこのうち460エラーは含まれないことです。
460はELBが応答に時間がかかっている時にクライアント側から切断された場合のエラー2になるため、かなり重いリクエストのときなどたまに発生することがあります。

HTTPCode_ELB_5XX_Count

ロードバランサから送信される5xxエラーの総数になります。1
501, 505, 561 についてはドキュメントに記載2がありますが、CloudWatchメトリクスとしては今の所存在しないようです。
そのため内訳は以下のようになります。

含まれるCloudWatchメトリクス

  • HTTPCode_ELB_500_Count
  • HTTPCode_ELB_502_Count
  • HTTPCode_ELB_503_Count
  • HTTPCode_ELB_504_Count

稼働率に用いる変数の集約

実際に稼働率を可視化する際はCloudwatchAlarmやGrafanaなどを用いますが、指定するメトリクス量が多く面倒です。
RequestCountを利用することで、指定するメトリクスを集約することができますのでご紹介します。

RequestCount

RequestCountは リスナールールによりターゲットが選択されると増分される値 です。1
一見してリクエスト総数と見做せそうですが、ターゲットを選択できなかったもの(ELB4xx,ELB500,ELB503)2 は含まないため、 以下のメトリクスの合計になります。

  • HTTPCode_Target_2XX_Count
  • HTTPCode_Target_3XX_Count
  • HTTPCode_Target_4XX_Count
  • HTTPCode_Target_5XX_Count
  • HTTPCode_ELB_3XX_Count
  • HTTPCode_ELB_502_Count
  • HTTPCode_ELB_504_Count

リクエスト総数の計算部分はRequestCountと被るメトリクスが多いので、以下のように変換することができます。

$$\mathrm{稼働率} = \frac{ELB3xx + ELB4xx + Target2xx + Target3xx + Target4xx}{\textcolor{blue}{ELB3xx + ELB4xx + ELB5xx + Target2xx + Target3xx + Target4xx + Target5xx}}$$ $$= \frac{ELB3xx + ELB4xx + Target2xx + Target3xx + Target4xx}{ \textcolor{blue}{RequestCount + ELB4xx + ELB500 + ELB503}}$$

さいごに

今回はCloudWatchメトリクスからWebサービスの稼働率を算出する方法についてご紹介しました。
実際はHTTPCode_ELB_4XX_Count には460エラーが、HTTPCode_ELB_5XX_Count には501,505,561エラーが含まれておらず、 あくまで近似値となりますのでご注意ください。
より正確な方法としては、ELB のアクセスログ3にステータスコード(elb_status_code)が出力されていますので、こちらのフィールドを集計 (全件 - 5xx / 全件) することを検討ください。
安定的なシステム運用の指標として、うまくご利用いただければ幸いです。


  1. Application Load Balancer の CloudWatch メトリクス - Elastic Load Balancing  ↩︎

  2. Application Load Balancer のトラブルシューティング - Elastic Load Balancing  ↩︎

  3. Application Load Balancer のアクセスログ  ↩︎

最後まで読んでいただき、ありがとうございます!
この記事をシェアしていただける方はこちらからお願いします。

recruit

DeNAでは、失敗を恐れず常に挑戦し続けるエンジニアを募集しています。