Azure SQL Database のコスト管理とリソース最適化アプローチ

この記事は[Microsoft Azure Advent Calendar 2024](https://qiita.com/advent-calendar/2024/azure) の3日目の記事です。
# 記事の概要
この記事では、Azure SQL Databaseの構成情報を基に、リソース使用状況を分析し、コスト削減方法のアプローチを記載しています。Azure CLIを使った構成確認の方法や、課金モデルの選択基準についても記載しています。Azure SQL Databaseの運用におけるコスト管理とリソース最適化の一助になれば幸いです。
# 1. データベース構成の確認

**確認方法**
```bash
az sql db show --name <DatabaseName> --server <ServerName> --resource-group <ResourceGroupName>
```
**出力結果例 (抜粋)**
```json
{
"currentBackupStorageRedundancy": "Geo",
"defaultSecondaryLocation": "japanwest",
"location": "japaneast",
 "maxSizeBytes": 1099511627776,
 "sku": {
    "capacity": 4,
    "family": "Gen4",
    "name": "GP_Gen4",
    "size": null,
    "tier": "GeneralPurpose"
  },
 }
```
構成情報と対応するJSON項目を整理した表を示します。
| **構成情報** | **JSON項目** | **値** |
| --- | --- | --- |
| サービス層 | "tier": "GeneralPurpose" |  General Purpose |
| SKUファミリー | "family": "Gen4" | Gen4 |
| vCore数 | "capacity": 4 | 4 |
| 最大ストレージ容量 | "maxSizeBytes": 1099511627776 | 1 TB |
| バックアップ冗長性 | "currentBackupStorageRedundancy": "Geo" | Geo 冗長 |
| プライマリリージョン | "location": "japaneast" | 日本東 |
| セカンダリリージョン | "defaultSecondaryLocation": "japanwest" | 日本西 |

このデータベースは、vCore ベースの購入モデルを採用しており、4vCoreをプロビジョニングしています。バックアップは、複数の地域での可用性を確保するGeo冗長ストレージが設定されています。

# 2. 使用状況の分析
**確認方法**
実際の使用状況を分析するため、今回はCPU使用率とストレージ使用量を確認していきます。
以下のコマンドで対象データベースのCPU使用率とストレージ使用量を取得します。結果がJSON形式で出力されるので、それを解析して使用状況を評価します。
```bash
az monitor metrics list \
  --resource "/subscriptions/<SubscriptionID>/resourceGroups/<ResourceGroupName>/providers/Microsoft.Sql/servers/<ServerName>/databases/<DatabaseName>" \
  --metric "cpu_percent" "storage" \
  --interval PT1H
```
**パラメータ**
| **パラメータ名** | **説明** |
| --- | --- |
| SubscriptionID | サブスクリプションのIDを指定 |
| ResourceGroupName | データベースが属しているリソースグループ名 |
| ServerName | SQLサーバーの名前 |
| DatabaseName | 対象のデータベース名 |
| metric | 取得するメトリクス名|
| interval PT1H | データポイント PT1M（1分）や P1D（1日）なども指定可能 |

**出力結果例 (抜粋)**
```json
{
  "timeseries": [
    {
      "data": [
        { "timeStamp": "2024-12-01T00:00:00Z", "average": 0.12 },
        { "timeStamp": "2024-12-01T01:00:00Z", "average": 0.15 }
      ]
    }
  ]
}
```

# 3. 分析結果例
**CPU使用率**
- **平均使用率**: 約0.173%　
- **過剰リソースの可能性**: 現在のCPU使用率が非常に低いため、4vCore構成は過剰である可能性

**ストレージ使用量**

- **平均使用量**: 約1.2GB
- **過剰リソースの可能性**: 現在の使用量を考えると、ストレージ容量の見直しが可能性

# 4. 最適化案

##  vCore数のスケールダウン

- **現在の構成**: 4vCore (GP_Gen4_4)　月額¥74,000（Azure公式の料金例）
- **提案される構成**: 2vCore (GP_Gen4_2)　月額¥37,000
- **vCore削減額**: ¥74,000 - ¥37,000 = ¥37,000の削減

**理由**

- CPU使用率の平均が約 0.173%と非常に低い状態
- トランザクション量が少ない環境では、4vCoreは過剰であり、2vCoreにスケールダウンすることで十分対応可能

**期待される効果**

- **コスト削減**: vCore数を半分にすることで、コンピューティングコストが大幅に削減
- **パフォーマンス維持**: 現在の低い使用率から判断すると、スケールダウンしてもパフォーマンスへの影響は軽微

## ストレージ容量の削減

- **現在の構成**: 最大ストレージ容量 1TB 月額¥11,000（Azure公式の一般価格）
- **提案される構成**: 最大ストレージ容量 10GB　月額¥110（1GBあたり¥11の単価）
- **ストレージ削減額**: ¥11,000 - ¥110 = ¥10,890の削減

**理由**

- 平均使用量が約1.2GBと非常に少ないため、1TBのプロビジョニングは過剰
- ストレージ容量を10GB程度に削減することで、不要なストレージコストを削減

**期待される効果**

- **コスト削減**: ストレージコストは使用量とプロビジョニング量に基づくため、大幅な削減が可能
- **管理効率向上**: 不要なストレージの削減により、データ管理が簡素化

## サーバーレスへの移行
- **現在の構成**: vCoreベース（4vCore）
- **提案される構成**: サーバーレス (Serverless) モデル

**サーバーレスとは**

- サーバーレスモデルでは、リソースが自動的にスケールし、アプリケーションがアイドル状態の場合にリソースの消費がゼロになるため、コストを大幅に削減できる
- 使用量に基づいて料金が発生するため、特に負荷が低い時間帯の場合に有効

**期待される効果**

- **コスト削減**: 負荷が変動するワークロードの場合、使用量に応じてコストが最適化
- **柔軟なスケール**: 使用状況に応じて、必要なリソースのみがプロビジョニング
- **運用負荷の軽減**: 自動スケールにより、管理の手間が軽減

**考慮点**

- サーバーレスでは、特定の使用量に応じた料金モデルが採用される
- 常に高いリソースを使用する場合は、従量課金がかえって高額になる可能性があるため注意
- スケールアップに伴う遅延やコールドスタートの影響

**サーバーレスと固定構成の比較表**
| **項目** | **サーバーレス** | **仮想コアベース (vCore)** |
| --- | --- | --- |
| **コスト構造** | 従量課金（秒単位で課金） | 固定料金（常時課金） |
| **スケーリング** | 自動（最小～最大vCoreを指定可能） | 手動 |
| **アイドル状態の料金** | 最小限の課金、またはゼロ | 常時課金 |
| **適用範囲** | 負荷変動が大きいアプリケーション向け | 常時稼働の高負荷システム向け |

# 5. 課金モデルの種類と選択のポイント
Azure SQL Databaseの課金モデルには、以下の2種類があります

1. **プロビジョニングモデル**（vCoreベース）
2. **DTU ベースモデル**

**確認方法**
```bash
az sql db show \
  --name <DatabaseName> \
  --server <ServerName> \
  --resource-group <ResourceGroupName> \
  --query "{name: name, tier: sku.tier, capacity: sku.capacity, family: sku.family}" \
  --output table
```

**出力結果：DTUベースの場合**
以下のように、Tierに「Standard」や「Premium」、Capacityに数値が表示される場合は、DTUベースの課金モデルを使用しています。
```bash
Name                Tier       Capacity    Family
------------------  ---------  ----------  ------
DatabaseName        Standard   20          null
```
- **Tier**: S1, S2, S3 などは「Standard」レベル
- **Capacity**: DTU（Database Transaction Unit）の数値


**出力結果：プロビジョニング（vCoreベース）の場合**
以下のように、Tierに「GeneralPurpose」や「BusinessCritical」、Familyに「Gen4」や「Gen5」が表示される場合は、プロビジョニングモデルを使用しています。
```bash
Name                Tier             Capacity    Family
------------------  ---------------  ----------  ------
DatabaseName        GeneralPurpose   2           Gen5
```
- **Tier**: GP（General Purpose）、BC（Business Critical）など
- **Capacity**: vCore数
- **Family**: SKUファミリー

**課金モデルの違い**
| **項目** | **プロビジョニング（vCore）** | **DTU ベース** |
| --- | --- | --- |
| **適用範囲** | 負荷が変動する大規模ワークロードに最適 | 単一の簡易アプリケーションや固定負荷向け |
| **スケーリングの自由度** | vCore 数、メモリ、ストレージを個別に調整可能 | DTU（CPU、メモリ、ストレージ一括管理） |
| **料金モデル** | 使用リソース（vCore数、ストレージ）に基づく | プリセットされたDTUパッケージ |

**DTUベースモデルが適している場合**

- リソース要件が固定的で、シンプルな管理を求める場合
- 小規模な開発環境やテスト環境

**プロビジョニングモデルが適している場合**

- 高い可用性やスケーラビリティが必要な場合
- リソース使用量に基づいたコスト最適化を行いたい場合
- パフォーマンスの変動が大きいワークロード

# 6. まとめ
Azure SQL Databaseのリソース構成を適切に管理し、使用状況に基づいて最適化を行うことは、運用コストの削減と効率的なパフォーマンス管理に直結します。この記事では、Azure CLI を活用して現在のリソース使用状況を把握し、最適化のポイントを整理しました。

特に、スタートアップや新規サービスでは、アクセス数やデータベース負荷が短期間で大きく変動することが多いため、柔軟なリソース管理が求められます。こうした状況に対応するためには、以下の取り組みが効果的です。

- Azure Monitorによる使用状況のリアルタイム監視
- Azureの自動スケール機能を利用することで、事前に用意したスケールルールに基づいて適切にリソースを増減
- Azure Advisorを活用し、コスト削減やパフォーマンス最適化の具体的な推奨事項を確認し、見落としを防ぐ

これらの機能や取り組みを適切に活用することで、変動するワークロードに対応しつつ、コスト効果の高い運用を目指すことができます。Azure SQL Databaseを最大限に活用し、柔軟でスケーラブルなサービス運用を実現を目指していきたいです。