Azure SQL Database のメトリックを取得して可視化する (EZMonitor)

# SQL Database で提供されている標準的なメトリックの取得方法
Azure で提供されている SQL Server ベースの PaaS (DBaaS) である、[SQL Database](https://docs.microsoft.com/ja-jp/azure/azure-sql/database/sql-database-paas-overview) では、プラットフォームの機能として様々な情報の取得を行うことができます。
- [Azure SQL Database と Azure SQL Managed Instance での監視とパフォーマンス チューニング](https://docs.microsoft.com/ja-jp/azure/azure-sql/database/monitor-tune-overview)
- [AI を使用してデータベース パフォーマンスの監視とトラブルシューティングを行う Intelligent Insights (プレビュー)](https://docs.microsoft.com/ja-jp/azure/azure-sql/database/intelligent-insights-overview)
- [Azure SQL Analytics (プレビュー) を使用した Azure SQL Database の監視](https://docs.microsoft.com/ja-jp/azure/azure-monitor/insights/azure-sql?toc=%2Fazure%2Fazure-sql%2Ftoc.json)
- [Azure SQL Database の Query Performance Insight](https://docs.microsoft.com/ja-jp/azure/azure-sql/database/query-performance-insight-use)

これらの情報から、SQL Database の稼働状況や、実行されているクエリの分析を行うことができます。

クエリの情報についてはクエリストアをベースとして情報の取得が行われているため、基本的な確認については、クエリストアの情報を成形して表示している Query Performance Insight で対応できるケースが多いのではないでしょうか。
リソースの使用状況のメトリックについても情報が取得されており、次のような項目が標準で取得されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33611/81b7d07b-be61-6eec-eca6-09bb156006b3.png)

取得されている情報は Log Analytics の「AzureMetrics」から確認することもできますので、自分でデータを活用することも可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33611/d2e9b071-a207-7331-18a2-d701d89e6ceb.png)


# 標準的なメトリックで足りていない情報を EZMonitor カバーする
基本的な情報については、プラットフォームの標準機能で取得されている内容で足りるかと思いますが、リソースの使用状況の分析を始めると、不足していると感じる情報が出てきます。
例えば、リソースの使用状況ですが、様々な情報を取得しているのですが、「割り当てられているリソースに対して、どの程度を使用しているかの % 表示」で示されていることが多いです。

SQL Database 今のサービスモデルになった際は DTU モデルというモデルが基本でした。(その前は Web / Basic がありましたが)

DTU モデルのリソース制限については [DTU 購入モデルを使用した単一データベースのリソース制限 - Azure SQL Database](https://docs.microsoft.com/ja-jp/azure/azure-sql/database/resource-limits-dtu-single-databases) で公開されています。

DTU モデルでは、使用可能な CPU のコア数 / メモリサイズ / ディスク性能については、明示的な値が公開されておらず、DTU という相対評価の値で性能が示されていました。
具体的なリソース上限の値が公開されていないサービスモデルでは「割り当てられているリソースに対して、どの程度使用しているかの割合」で、リソース使用状況のメトリックを示すのが、統一的なデータの公開となると思いますので、% 表示を基本とするほかになかったのではないでしょうか。

現在は vCore モデルも提供されており、こちらについては[仮想コア購入モデルを使用した単一データベースに対するリソース制限](https://docs.microsoft.com/ja-jp/azure/azure-sql/database/resource-limits-vcore-single-databases)で公開されているように、使用可能なリソースの具体的な値が公開されています。
このような情報が公開されているので、vCore モデルは「リソースの使用可能な上限に透明性がある」というような言い方をすることもあります。
ただし、現状 vCore モデルを使用していても標準的なメトリックについては、リソース使用状況は割合 (%) で取得されていることが多く、具体的なリソースの使用状況を標準メトリックから判断できないことがあります。

リソースの使用状況については、当初から提供されている次の DMV で確認をすることができます。
- [sys.resource_stats](https://docs.microsoft.com/ja-jp/sql/relational-databases/system-catalog-views/sys-resource-stats-azure-sql-database?view=azuresqldb-current)
- [sys.dm_db_resource_stats](https://docs.microsoft.com/ja-jp/sql/relational-databases/system-dynamic-management-views/sys-dm-db-resource-stats-azure-sql-database?view=azuresqldb-current)

これらの DMV で公開されている情報は、ポータルから確認できるメトリックに似ている情報となりますので % による割合での表示となっており、DTU / vCore ともに、割合での確認となります。

リソース使用状況の分析をしていると、確認したい情報として「具体的にリソースをどのぐらい (CPU : 何 % / ディスク IOPS, スループット / メモリ使用状況 (MB)) 使用しているのか」を確認したいことがないでしょうか。

そのような場合は、標準で取得されているメトリックだけでなく、次のような DMV を活用する必要が出てきます。
- [sys.dm_user_db_resource_governance](https://docs.microsoft.com/ja-jp/sql/relational-databases/system-dynamic-management-views/sys-dm-user-db-resource-governor-azure-sql-database?view=azuresqldb-current)
- [sys.dm_resource_governor_resource_pools_history_ex](https://docs.microsoft.com/ja-jp/sql/relational-databases/system-dynamic-management-views/sys-dm-resource-governor-resource-pools-history-ex-azure-sql-database?view=azuresqldb-current)
- [sys.dm_resource_governor_workload_groups_history_ex](https://docs.microsoft.com/ja-jp/sql/relational-databases/system-dynamic-management-views/sys-dm-resource-governor-workload-groups-history-ex-azure-sql-database?view=sql-server-ver15)
- [sys.dm_os_performance_counters](https://docs.microsoft.com/ja-jp/sql/relational-databases/system-dynamic-management-views/sys-dm-os-performance-counters-transact-sql?view=sql-server-ver15)
- [sys.dm_io_virtual_file_stats](https://docs.microsoft.com/ja-jp/sql/relational-databases/system-dynamic-management-views/sys-dm-io-virtual-file-stats-transact-sql?view=sql-server-ver15)

これらの DMV の情報を活用することで、具体的なリソースの使用状況を数値として使用することができます。

# EZMonitor によるメトリックの取得
SQL Database のリソースの可視化の仕組みは、いくつか作ったのですが、できるだけ、既存の環境のリソース使用状況の仕組みと合わせる形で実装していたため、今までは案件ごとに環境に合わせて作っていました。

毎回環境に合わせて作っていると、自分の中でのナレッジが散逸してしまうため、自分が使用している環境向けに Auzre 内にクローズしてメトリック収集の仕組みを作ろうと思って、対応していたものが [EZMonitor](https://github.com/MasayukiOzawa/EZMonitor) となります。
(_ex 系の DMV と tempdb 周りの情報取得がまだ組み込めていないのですが)

仕組みと展開方法ついては GitHub の README に記載していますが、
- Timer トリガーの Azure Functions で定期的にクエリを実行
- Log Analytics に情報を取得
- Azure Workbook で情報を可視化
というような作りとなっています。

<a href="https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FMasayukiOzawa%2FEzMonitor%2Fmaster%2FDeployments%2Fazuredeploy.json" target="_blank">
  <img src="https://aka.ms/deploytoazurebutton" />
</a>でテンプレート展開できるようにもなっています。

次のような内容を設定して、展開時をすることで、情報の取得を行えるようになっています。
(Basic / Standard / General Purpose では、権限の問題で、ログインに管理者を指定しないといけないのがちょっとネックなのですが)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33611/49d0fc08-567b-f0d3-c0cd-c8ad20687ce7.png)

デプロイが終わると、次のようなリソースが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33611/a8aee8bb-f494-2e08-e07f-77e0b36c8d05.png)

Azure ブックのリソースが取得している情報の可視化となります。
Function が動き情報の取得が開始されると、Azure ブックで次のようなレポートを確認することができるようになります。
(Function が安定して稼働するまでには少し時間がかかります)

できるだけ実際の使用状況を可視化するようにしていますので、実際のリソース使用の上限はどれくらい設定されているか、ディスクであれば、何 IOPS / 何 MB/sec 発生しているかを確認できるようにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33611/d2bcf530-8d25-a48c-a50f-a143c9c5b7f1.png)

DTU モデルについても、どの程度のリソースが割り当てられているかを、可能な範囲で確認できるようにしていますので、利用している DTU モデルで、ハードウェアスペックがどの程度のものなのかを確認することもできます。

Hyperscale を使用している場合は、ローカルの RBEPX の情報についても確認ができるようにしています。

EZMonitor は SQL Database に特化した情報の取得を行っていますが、中で実行しているクエリについては、汎用的なものもが大半ですので、クエリの部分だけを使用して他の環境 (SQL Server / RDS for SQL Server / Cloud SQL for SQL Server) 向けに実行することもできるかと思います。

簡単な操作でリソース使用状況を確認できるダッシュボードを展開できると楽でいいですね。