💰

Azure Database for MySQLのIOPS設定の変更で月額n百万円のコストダウンが見込めました

2024/09/27に公開

こんにちは。イオンスマートテクノロジー株式会社(AST)でSREチームの林 aka もりはやです。

本記事はAzureのマネージドなMySQLである”Azure Database for MySQL Flexible Server”(以後はDB)の2つのIOPS設定の機能やコストについてまとめたシリーズの第2弾となり、IOPS設定の変更によるコストを試算したら大変効果がありそうだとわかった話です。

本記事はあくまで試算の段階で、成果報告は次の第3弾の記事で予定しています。(うまくいけば...)

なお、今回のキーとなるIOPS設定"Auto scale IOPS"について私見をまとめた第1弾の記事はこちらになりますので興味がある方はご覧ください。
https://zenn.dev/aeonpeople/articles/2c2f706c0ae173

TL;DR

  • 現環境の多くはAzure Database for MySQL Flexible Serverの固定IOPS設定である"Pre-provisioned IOPS"を利用している
  • "Auto scale IOPS"は有用そうだし、コスト効果もありそうだと判断した(第1弾の記事を参照)
  • DBの数が多いため"Azure Resource Graph Explorer"を利用してDBとIOPS値の一覧を取得した
  • コスト比較のため直近30日間の"Storage IO Count"の取得を azure-cli で取得した
  • 上記をExcelで集計したところ”月額n百万円のコストダウン”を見込めた
  • "Auto scale IOPS"は万能ではなく、急激なIOスパイクに追いつかない可能性があるため要注意

現状は固定IOPSの"Pre-provisioned IOPS"が主体

現環境を調査したところ、多くのDBが固定IOPSのPre-provisioned IOPSを利用していることがわかりました。

こちらに関しては第1弾の記事でも触れましたが、廃止となった"Azure Database for MySQL - Single Server"からの移行に際し、従来の固定IOPS設定をそのまま流用することで、DB移行によるリスクを最小限とする試みがあったと考えられます。

動的に最適化される"Auto scale IOPS"が良さそうに見えてきた

日々のSRE活動の一つであるコスト削減の取り組みの中で、動的に最適化される"Auto scale IOPS"の適用を行うことでコスト削減が見込める可能性を感じました。

このSingle Serverにはなかった新しいIOPS設定について、第1弾のブログを通して理解を深めたところその思いは確信に近いものになりました。

実際に試算してみる

よって、緊急度の高いタスクが落ち着いたタイミングを見つけて実際に試算してみることにしました。(なおこういった動きが取れるのはイケてる同僚氏たちが揃うSREチームの中でタスク配分がうまく行っているためです、改めてここで感謝!)

多数のDBの設定値の一覧を取得するため"Azure Resource Graph Explorer"を利用

イオンのトータルアプリ iAEONをはじめ、多くのお客様やグループ内関係者が利用するサービスである当社のシステムは大規模と言えます。

加えてAzure Kubernetes Service (以後AKS)を活用したマイクロサービスによるシステムは多くのDBを持つ構成となっています。

これらのDBのIOPS設定をWeb画面から一つずつ確認していくのは現実的ではありませんし、Terraformコードから探索するのもシステムや環境別にディレクトリ分割されていることから難しいと考えました。

そこで利用したのが"Azure Resource Graph Explorer"です。

https://learn.microsoft.com/en-us/azure/governance/resource-graph/overview

上記のページより一部を引用します。

Resource Graph has the ability to query at scale across a given set of subscriptions so that you can effectively govern your environment.

つまり、Azureの大規模な環境に対していい感じにクエリを実行して結果を得られるサービスであり、”多数のDBのIOPS設定を一覧化する”目的にマッチするサービスでした。

"Azure Resource Graph Explorer"では、私にとって馴染みのなかった"Kusto Query Language (KQL) "と呼ばれるものを利用します。

https://learn.microsoft.com/en-us/azure/governance/resource-

使用したKQL

以下はドキュメントやAzure OpenAIの力を借りながら組み立てたKQLクエリです。

resources
| where type == "microsoft.dbformysql/flexibleservers"
| extend storageProfile = properties.storage
| extend storageIops = tostring(storageProfile.iops)
| project name, resourceGroup, location, storageIops, sku = sku.name, id
| order by name asc

詳細な解説はしませんが、ポイントとなるMySQL Flexible serversの iops の記述があるのは以下のドキュメントです。(このドキュメント、色々調べた結果発見しましたが、ゼロ知識からどうやってたどり着けば良いのか悩ましいと感じました...)

https://learn.microsoft.com/en-us/azure/templates/microsoft.dbformysql/flexibleservers?pivots=deployment-language-bicep#storage

KQLの結果

上記のクエリを実行した結果が以下のようになります。(画像はマスクしています)

この結果はCSVとしてダウンロードができ、以下のようになります。

"NAME","RESOURCEGROUP","LOCATION","STORAGEIOPS","SKU","ID"
"pmhmqjemorih001","pmhrgjemorih001","japaneast","38000","Standard_E32ds_v4","/subscriptions/1234567-1234-1234-1234-12345678901/resourceGroups/pmhrgjemorih001/providers/Microsoft.DBforMySQL/flexibleServers/pmhmqjemorih001"
"pmhmqjemorih002","pmhrgjemorih001","japaneast","6400","Standard_D4ds_v4","/subscriptions/1234567-1234-1234-1234-12345678901/resourceGroups/pmhrgjemorih001/providers/Microsoft.DBforMySQL/flexibleServers/pmhmqjemorih002"
...

Pricingページより固定IOPSの場合は以下の金額になります。

Type Price Unit
Pre-provisioned IOPS
(Additional IOPS)
$0.06 IOPS/month

上記例の1行目のDBは38000 が設定した固定IOPSの値であり、計算すると
38000 * $0.06/month = $2280/month = およそ月額32万円強
となります。

余談ですが一見謎に見えるリソース名 pmhmqjemorih001 については、私も入社前に感銘を受けた以下の記事をご参照ください。

https://zenn.dev/aeonpeople/articles/0b4a4be83d0dfd

簡単に解説すると以下です。(例として作ったもので実際には存在しません)

pmhmqjemorih001 を紐解くと...

  • p: Production環境
  • mh: システム名morihayaのmh
  • mq: MySQL
  • je: Japan Eastリージョン
  • morih: 利用用途はmorihaya
  • 001: 1号機

私は9月で入社半年を迎えましたが、今となってはこのスルメネーミングなしではやっていけないほどです。(実に味わい深いです)

直近30日間の"Storage IO Count"の取得を azure-cli で取得

"Azure Resource Graph Explorer"でDBのIOPS設定値をまとめて取得することができましたが、目的は固定IOPSである"Pre-provisioned IOPS"を利用している現状と"Auto scale IOPS"にした場合のコスト比較です。

PricingページよりAuto scale IOPSの金額表は以下の通りです。

Type Price Unit
Auto scale IOPS
(Paid IO Locally redundant storage (LRS))
$0.29 per million IOPS
Auto scale IOPS
(Paid IO Zone redundant storage (ZRS)
$0.363 per million IOPS

固定IOPSが月額単位であるため、同じように月間(30日間)のIO Countを取得し $0.29 per million IOPS でコストを算出する必要があります。ここでは説明をシンプルにするためLRSの金額で統一します。

まとめて"Azure Resource Graph Explorer"で出力したいと考えたのですが、調べた範囲ではメトリクスを取得することはできないようでした。

このため"Azure Resource Graph Explorer"からダウンロードしたCSVファイルをリストファイルとして利用し azure-cli を用いて取得することとしました。azure-cli 以外にいくつか手段はありましたが、手慣れたシェルでシュッとやりたいと考えた選択です。

使用した azure-cli コマンド

以下が組み立てたコマンドになります。環境によっては事前に az login が必要です。

#!/bin/bash

# CSVデータを含むファイル名を指定
input_file="data.csv"

# ファイルから各行を読み込む
while IFS=, read -r name group region iops vm_type resource
do
  # 各フィールドの値をトリムしてダブルクォートを削除
  name=$(echo $name | tr -d '"')
  iops=$(echo $iops | tr -d '"')
  resource=$(echo $resource | tr -d '"')

  # 各フィールドの値を表示
  echo -n "Name: $name ,"
  echo -n "IOPS: $iops ,"

  # 計算
  echo -n "Total IOPS: "
  az monitor metrics list --resource $resource --metric "storage_io_count" --interval P1D --aggregation Total  --start-time "$(date -v-31d +%Y-%m-%dT%H:%M:%SZ)" --end-time "$(date -v-1d +%Y-%m-%dT%H:%M:%SZ)" | jq '[.value[].timeseries[].data[].total] | add'

done < "$input_file"

詳細な解説はしませんが、ポイントをいくつか記載します。

  • input_file="data.csv" 読み込むCSVファイル名を指定します
    • *"Azure Resource Graph Explorer"からダウンロードした場合はAzureResourceGraphResults-Query.csvのような名前ですが、長いためリネームを前提としています
  • while IFS=, read, 区切りでカラムを変数に格納
  • az monitor metrics list でメトリクスを取得
    • interval P1D は30日間欲しいため時間ではなく日を指定
    • --start-time には -31日前 を指定
      • なおMacbookでの実行であるため -v-31d としたが、GNU系なら -d '31 days ago' とします
    • --end-time には当日だと24時間分ではない懸念があるため前日を指定
  • jq '[.value[].timeseries[].data[].total] | add' で30日分の結果を合算

azure-cli の結果

上記のシェルを実行すると以下のような結果を入手できます。

Name: pmhmqjemorih001 ,IOPS: 38000 ,Total IOPS: 280000000
Name: pmhmqjemorih002 ,IOPS: 38000 ,Total IOPS: 100000000
...

上記例の1行目のDBは280000000 が30日間で利用されたIOPSの合計値であり、計算すると
280000000 * $0.29 / 1000000 = $812/month = およそ月額11万円強
となります。

固定IOPSの場合を改めて引用しますが、IOPS固定の場合”月額32万円強”に対して動的IOPSにすると”月額11万円強”でおさまった可能性が見えてきます。

上記例の1行目のDBは38000 が設定した固定IOPSの値であり、計算すると
38000 * $0.06/month = $2280/month = およそ月額32万円強
となります。

出力結果をExcelなどで集計

ここまで来ればほぼゴールです。上述したような計算を各DBに対しExcelに取り込んだ上で行い集計しました。

結果として、本記事の件名にあるように"月額n百万円のコストダウンが見込め"ましたので今後のコスト削減の取り組みの一つとして行なっていく計画です。

注意: Auto scale IOPSは急激なスパイクに間に合わないリスク

コスト削減の観点で大変素晴らしい"Auto scale IOPS"ですが万能ではないことに注意が必要です。信頼できる筋より以下の助言をいただきましたので明記しておきます。(何かを変更するときにリスクが0になることは基本ありませんね...)

  • 基本的にはAuto scale IOPSの利用を推奨する
  • しかしIOPSの最適化が急激なスパイクに追いつかないリスクがある
  • 変更にあたっては過去のメトリクスよりスパイクがないことを確認する
  • スパイクがあった場合は(なくても可能なら)負荷試験によって影響を確認する

まとめ

以上が「Azure Database for MySQLのIOPS設定の変更で月額n百万円のコストダウンが見込めた」話となります。結果を数週間or数ヶ月後に成果として公開できるよう取り組んでいきますが、リスクにどう向き合うかは大変悩ましいところです。

なお、内容について公式ドキュメントを参照しながら正確性に気をつけましたが、誤りは全て著者である私の責任となりますため、発見された方は(可能なら優しく)教えていただけると大変ありがたいです。(特に計算式のあたり)

それではみなさまEnjoy コスト最適化&Azure!!

イオングループで、一緒に働きませんか?

イオングループでは、エンジニアを積極採用中です。少しでもご興味もった方は、キャリア登録やカジュアル面談登録などもしていただけると嬉しいです。
皆さまとお話できるのを楽しみにしています!

GitHubで編集を提案
AEON TECH HUB

Discussion