本文教您分析 Azure 虛擬機器 (VM) 上 SQL Server 的 I/O 效能,以找出超過虛擬機器和資料磁碟限制所造成的問題。
概觀
雖然有各種工具可協助您對 SQL Server 效能問題進行疑難排解,但若要在 Azure VM 上有效地解決問題,請務必了解主機層級和 SQL Server 執行個體發生的情況,通常,將主機計量與 SQL Server 工作負載相互關聯可能是一項挑戰。 Azure VM 上的 SQL Server 可讓您輕鬆地識別 IOPS (每秒輸入/輸出) 引起的效能問題以及因超出虛擬機器和資料磁碟限制而導致的輸送量節流。
Azure 入口網站中提供了示範此問題的效能計量以及解決此問題的潛在步驟,並且可以使用 Azure CLI 進行查詢。
在 Azure 入口網站中,您的 SQL 虛擬機器 資源的 儲存體 窗格可協助您:
- 管理您的儲存體組態
- 識別 I/O 節流
- 評估您的系統以取得 I/O 相關的最佳做法
了解計量
[I/O 分析] 索引標籤依賴 Azure 度量來識別磁碟延遲情況,以及虛擬機器 (VM) 或磁碟 I/O 限制。 Azure 計量每隔 30 秒取樣一次,並匯總至一分鐘。
系統會監視節流和磁碟延遲。 某些限速調節是預期的,通常會被忽略,除非也有磁碟延遲。 如果在連續 5 分鐘期間觀察到超過 500 毫秒的磁碟延遲,則系統會:
- 更深入探討效能計量
- 識別受限的資源
- 提供潛在的根本原因和風險降低步驟
下表說明用於識別有問題的節流問題的 Azure 計量:
Azure 指標 | 度量說明 | 有問題的情況 | I/O 節流結論 |
---|---|---|---|
磁碟延遲 (預覽版) | 在監視期間完成資料磁碟 IO 的平均時間。 值以毫秒為單位。 | 在一段連續的 5 分鐘期間 > 500 毫秒 | 系統有延遲問題,需要進一步調查潛在節流。 |
VM 快取的 IOPS 消耗百分比 | 根據完成的總 IOPS 與最大快取虛擬機器 IOPS 限制計算出的百分比。 | 在連續 5 分鐘期間,>≥ 95% | VM 發生節流問題。 SQL 虛擬機器上執行的應用程式充分利用虛擬機器可用的最大快取 IOPS 容量 – 應用程式的儲存體需求超出了虛擬機器基礎儲存體組態提供的快取 IOPS。 |
VM 快取頻寬消耗百分比 | 根據完成的磁碟輸送量總數與最大快取虛擬機器輸送量計算的百分比。 | 在連續 5 分鐘期間,>≥ 95% | VM 發生節流問題。 SQL 虛擬機器上執行的應用程式利用最大可用快取磁碟頻寬進行資料傳輸 - 應用程式的資料傳輸需求超過虛擬機器基礎儲存體組態提供的快取頻寬資源。 |
VM 未快取 IOPS 消耗百分比 | 計算虛擬機器上完成的總 IOPS 超過未快取虛擬機器 IOPS 上限的百分比。 | 在連續 5 分鐘期間,>≥ 95% | VM 發生節流問題。 SQL 虛擬機器上執行的應用程式利用虛擬機器可用的允許的最大未快取 IOPS 容量 – 應用程式的儲存體需求超過虛擬機器基礎儲存體組態提供的未快取 IOPS 資源。 |
VM 未快取頻寬消耗百分比 | 以虛擬機器上完成的總磁碟吞吐量相對於佈建的虛擬機器吞吐量上限計算的百分比。 | 在連續 5 分鐘期間,>≥ 95% | VM 發生節流問題。 SQL 虛擬機器上執行的應用程式利用允許的最大未快取磁碟頻寬進行資料傳輸 - 應用程式的資料傳輸需求超過虛擬機器基礎儲存體組態提供的未快取頻寬資源。 |
已使用的資料磁碟 IOPS 百分比 | 根據完成的資料磁碟 IOPS 相對於配置的資料磁碟 IOPS 計算的百分比。 | 在連續 5 分鐘期間,>≥ 95% | 存在硬碟速度限制。 SQL 虛擬機器上執行的應用程式達到已佈建資料磁碟的 IOPS 限制 - 應用程式的儲存體需求超過所選磁碟組態的效能功能。 |
已使用的資料磁碟頻寬百分比 | 完成的資料磁碟吞吐量相對於佈建的資料磁碟吞吐量所計算的百分比。 | 在連續 5 分鐘期間,>≥ 95% | 存在硬碟速度限制。 SQL 虛擬機器上執行的應用程式達到已佈建資料磁碟的 IOPS 限制 - 應用程式的儲存體需求超過所選磁碟組態的效能功能。 |
I/O 分析結果
根據過去 24 小時內的效能指標分析,I/O 分析得出結論:
- 無速度限制
- VM 層級的 I/O 節流
- 磁碟層的 I/O 節流
沒有 I/O 節流問題
如果您遇到效能問題,但沒有磁碟延遲,則效能問題不是因 I/O 節流問題所致。 您需要調查其他區域。 您可以使用 Azure VM 上 SQL Server 的最佳做法檢查清單,來確保您的系統已有效設定,或尋找對 SQL Server 效能進行疑難排解的實用連結。 如果啟用 SQL 最佳做法評量功能,您可以看到 SQL Server VM 的建議完整清單。
虛擬機層級 I/O 節流問題
Azure 虛擬機器是雲端式運算資源,針對各種工作負載有不同的系列和大小,每種資源都有不同的功能和效能特性。 對於 SQL Server 工作負載,一般而言,建議的 SQL Server 工作負載系列是記憶體最佳化的工作負載,例如 Ebdsv5、M 和 Mv2 系列。
VM 的大小決定了 SQL Server 執行個體可用的 vCPU、記憶體和儲存體的數量。 相較於儲存體,客戶可相對輕鬆地根據應用程式資源需求調整虛擬機器大小並增加或減少虛擬機器。 由於 IOPS 和輸送量可能會在 VM 層級節流,因此請根據效能需求和工作負載成本選擇適當的 VM 大小。
如果您要移轉至 Azure,您可以使用 SKU 建議 工具,分析您目前的 SQL Server 組態和使用方式,並建議 Azure 中工作負載的最佳 VM 大小。
以下 Azure 指標用於確定工作負載是否因超過 VM 所設定的限制而被限制:
- VM 快取 IOPS 的使用百分比
- 消耗的 VM 快取頻寬百分比
- 虛擬機器 (VM) 未快取的 IOPS 使用百分比
- VM 未快取頻寬使用百分比
請考慮下列有關 VM 節流的重點:
- 您可以透過調整 VM 系列內的虛擬機器大小,來增加記憶體、虛擬核心、輸送量和 IOPS。
- 您無法將 VM 大小減少到資料磁碟數目超過目標 VM 大小的資料磁碟上限的層級。
- 確定節流模式的模式非常重要。 例如,不常發生的節流峰值可以透過微調工作負載來解決,而持續的峰值可能表示基礎儲存體無法處理工作負載。
磁碟層級 I/O 節流問題
對於 SQL 虛擬機器客戶而言,儲存體是適當設定以最佳化效能的最重要層面,因為修改儲存體比調整虛擬機器大小更具挑戰性。。 例如,進行任何變更以增加進階 SSD 磁碟的 IOPS 或輸送量都需要建立新的儲存集區。 因此,在規劃階段最佳化儲存體組態的價格和效能至關重要,以避免部署後出現效能問題。
下列 Azure 指標用於判斷工作負載是否因超過磁碟的限制而受到節流:
已使用的資料磁碟 IOPS 百分比
已使用的資料磁碟頻寬百分比 請考慮下列有關磁碟層級 I/O 節流的重點:
資料磁碟對於 SQL Server 效能至關重要。 建議將 SQL Server 資料 (.mdf) 和記錄 (.df) 檔案放在資料磁碟上。
若要在資料磁碟層級進行節流,請啟用讀取快取功能(若支援此功能)。
已使用的資料磁碟 IOPS 百分比
資料磁碟 IOPS 消耗百分比度量指標測量磁碟層級的 IOPS 使用量。 一般而言,高 IOPS 需求與高交易式 OLTP 型應用程式和工作負載關聯。 下列案例或條件可能會超過資料磁碟 IOPS 限制:
- 高交易工作負載 (IOPS):如果應用程式正在處理涉及頻繁讀取和寫入作業的大量資料庫交易,它可以快速取用配置的 IOPS。
- 效率不佳的查詢:最佳化效能不佳的 SQL 查詢或資料擷取作業可能會導致 I/O 活動過多,取用的 IOPS 超出預期。
- 並行使用者:如果多個使用者或工作階段同時存取資料庫並產生 I/O 要求,累積效果可能會導致達到 IOPS 限制。
- 爭用資源:如果基礎實體基礎結構與其他租用戶或工作負載大量共用,可能會影響虛擬機器可用的 IOPS。
- 暫時尖峰:工作負載的暫時尖峰 (例如,批次處理或資料移轉) 可能會導致 I/O 需求突然增加,超過配置的 IOPS。
- 小型磁碟大小:如果佈建的資料磁碟大小相對較小,IOPS 容量可能會受到限制。 個別較小的磁碟具有較低的 IOPS 限制,如果應用程式的需求超過此限制,則 [已使用的資料磁碟 IOPS 百分比] 將達到 100%。
- 磁碟類型不足:為 I/O 密集型應用程式選擇效能較低的磁碟類型 (例如標準 HDD) 可能會導致 IOPS 限制。
- 未最佳化的磁碟等量大小:如果儲存體組態未針對工作負載最佳化,可能會導致次佳的 IOPS 效能。
請考慮下列步驟,以避免超過資料磁碟 IOPS 限制:
- 最佳化 SQL 查詢和資料庫設計,以將不必要的 I/O 作業降至最低。
- 選擇符合您應用程式 IOPS 需求的適當磁碟類型 (標準 SSD 或進階 SSD)。
- 使用較大的磁碟大小來增加可用的 IOPS 容量。
- 使用 RAID 組態將 I/O 分散到多個資料磁碟中。
已使用的資料磁碟頻寬百分比
已使用的資料磁碟頻寬百分比 Azure 計量會測量磁碟層級的頻寬使用率。 一般而言,高吞吐量需求通常與資料倉儲、資料集市、報告、ETL 以及其他資料分析工作負載相關聯。
下列案例或條件可能會超過資料磁碟頻寬限制:
- 大型資料傳輸:磁碟與 SQL 資料庫之間頻繁、大規模的應用程式資料傳輸,可快速取用可用的資料磁碟頻寬。
- 大量資料載入:與大量資料插入、更新或匯入關聯的磁碟傳輸活動可能會導致高頻寬耗用量。
- 資料倉儲或分析:涉及繁重資料倉儲、分析處理或報告的應用程式可能會產生大量資料移動,可能導致超過頻寬限制。
- 高資料備援技術/複寫:與使用磁碟型複寫、資料鏡像或其他備援機制關聯的資料複製可能會導致頻寬飽和。
- 資料備份與還原:頻繁的資料備份、快照或還原程序可能會耗用大量的資料磁碟頻寬。
- 平行查詢執行:涉及大量資料掃描或聯結的平行查詢可能會導致大量資料移動,從而導致頻寬使用。
- 提升的網路流量:高網路活動 (例如,虛擬機器與其他資源之間的資料傳輸) 可能會間接影響資料磁碟頻寬可用性。
- 磁碟類型不足:為資料傳輸要求較高的應用程式選擇效能較低的磁碟類型可能會導致超過頻寬限制。
- 並行資料密集作業:存取和傳輸相同磁碟上的資料的多個並行程序或工作階段的合併效果可能會導致達到頻寬限制。
- 未最佳化的查詢或 ETL 程序:最佳化效能不佳的 SQL 查詢或擷取、轉換和載入 (ETL) 程序可能會導致過多的資料移動,從而導致過多的頻寬耗用量。
請考慮下列步驟,以避免超過資料磁碟頻寬限制:
- 最佳化資料傳輸作業,以將不必要的資料移動降至最低。
- 請考慮使用效能較高的磁碟類型,以提供更高的頻寬容量,例如進階 SSD 或進階 SSD v2。
- 使用分割或分區等技術將資料分散到多個磁碟中。
- 最佳化和平行處理查詢和資料處理,以減少資料移動。
- 使用壓縮和有效率的資料儲存機制來減少傳輸的資料量。
- 監視效能計量,並視需要擴大儲存體組態。 進階 SSD v2 可讓客戶視需要隨選調整 IOPS 和輸送量。
- 請務必定期監視和分析效能計量,以識別 IOPS 限制的原因,並採取適當的動作來最佳化 SQL 虛擬機器的儲存體效能。
提示
定期監視效能計量、微調資料傳輸作業和最佳化磁碟組態,可確保 SQL 虛擬機器的資料磁碟效能保持最佳狀態且不會超過限制。
沒有節流的延遲
沒有節流的延遲是指即使記憶體系統未達到最大 IOPS 或輸送量限制,仍會發生的數據存取或處理延遲。 Azure VM 中的延遲可能來自各種來源,包括作系統的 I/O 堆棧、SQL Server 處理、網路負荷或 Hypervisor 排程。 識別延遲的原因對於優化 Azure VM 上的 SQL Server 效能很重要。
如果在未節流的情況下偵測到延遲,您會在 [記憶體] 窗格的 [I/O 分析] 索引標籤上看到下列警告:Warning: High disk latency detected without throttling
。
下列列出延遲的可能原因,而不需要節流:
- 高 CPU 使用率:大量 CPU 負載可能會降低 I/O 作業的速度,因為 CPU 正忙於加密、壓縮或查詢執行等工作。 這在具有較少核心的 VM 中特別普遍。 當 CPU 週期無法使用時,I/O 要求可以等候較長的時間進行處理,即使未達到記憶體限制,仍會增加延遲。 例如,執行 CPU 密集程式的 VM,例如數據加密,可能會延遲 SQL Server I/O 作業,而導致查詢回應時間變慢。
- VM 上的記憶體不足:在 SQL Server 中,記憶體對於快取數據而言非常重要,這可減少對磁碟 I/O 的需求。 如果記憶體受到限制,SQL Server 可能需要更頻繁地從磁碟讀取,這會增加延遲。 這在記憶體較少或記憶體密集的背景進程競爭資源時,在 VM 中特別相關。 這可以間接增加記憶體延遲,因為需要更頻繁的磁碟作業來處理工作負載,即使未達到 IOPS 限制也一樣。
- 背景進程:VM 上的其他行程 -- 例如防病毒軟體、備份或維護工作 (例如 Windows Update) - 可以取用 CPU、記憶體或磁碟 I/O 資源,以延遲 SQL Server 作業。 效率不佳的篩選驅動程式可能會使這個效果惡化。 這些程式會與 SQL Server 競爭系統資源,導致 I/O 延遲顯示為記憶體延遲。 例如,同時讀取許多檔案的防毒掃描可以減少 SQL Server 可用的磁碟頻寬,進而增加資料庫交易的延遲。 此外,若沒有設置正確的防毒排除設定,可能會在不需要節流的情況下導致 Azure 虛擬機器上的 SQL Server 出現延遲問題,這主要是由於磁碟 I/O 增加、篩選驅動程式干擾和資源競爭所引起的。
- 較低階層式記憶體使用量:選擇較低層級的記憶體選項,例如標準 HDD,而不是進階 SSD 或 Ultra 磁碟,由於這些磁碟的固有設計,即使未達到 IOPS 限制,也會帶來較高的基準延遲。 雖然符合成本效益,但較低層記憶體並未針對效能敏感的 SQL Server 工作負載進行優化,這會導致數據存取速度變慢。 例如,使用標準 HDD 來節省成本的客戶,可能會因為磁碟自然較高的延遲而遇到較慢的查詢效能。
- 記憶體設定不足:無法將您的記憶體設定為針對 SQL Server 工作負載進行優化,可能會導致延遲而不進行節流。 例如,不正確的磁碟快取設定可能會降低效能。 Microsoft建議在 Azure VM 上使用進階 SSD v1 搭配 SQL Server 時,啟用數據磁碟的唯讀快取,以及停用記錄磁碟的快取。 設定錯誤的快取可能會讓讀取或寫入作業變慢。 例如,在裝載 SQL Server 數據文件的數據磁碟上停用讀取快取,可降低大量讀取工作負載的效率,增加延遲。
- SQL Server 資料庫爭用:效率不佳的查詢(例如,完整表掃描而非索引查閱),或 SQL Server 內的鎖定爭用可能會增加 I/O 需求或延遲數據存取,這表示記憶體延遲。 應用層面的問題可能會在不超過存儲子系統限制的情況下造成負擔,特別是在交易工作負載中常見的小型隨機 I/O 模式中。 例如,在大型數據集上執行完整數據表掃描的效能不佳的查詢,會從磁碟讀取過多的數據,相較於索引查詢,提升 I/O 負載和延遲。
如果您在沒有節流的情況下遇到延遲,請考慮下列步驟來解決延遲:
- 監視和管理 CPU 使用量:使用 Azure 監視器或資源監視器等工具來追蹤 CPU 使用率。 如果 CPU 負載很高,請優化 SQL 查詢或升級至具有更多虛擬核心的 VM。
- 監視記憶體使用量:請確定 VM 大小有足夠的記憶體供 SQL Server 工作負載使用,並使用 E 系列或 M 系列等 VM 大小 與較高的記憶體對虛擬核心比率。 使用性能監視器或 Azure 監視器來監視記憶體使用量,以識別壓力點。 如有需要,請考慮相應增加記憶體。
- 仔細排程背景工作:在離峰時段執行大量資源工作(例如備份或防毒掃描),以避免與 SQL Server 競爭資源。
- 選取正確的儲存層:評估較低層記憶體 (例如標準 HDD) 是否符合您的效能需求。 對於重要的 SQL Server 工作負載,請選擇進階 SSD 或 Ultra 磁碟,以將延遲降到最低。
- 正確設定快取:針對 Premium SSD(v1),資料磁碟應設定為唯讀快取,而記錄磁碟則不應設定快取。 確認 VM 或記憶體變更後的設定,因為進階 SSD v2 和 Ultra 磁碟不支援快取。
- 優化 SQL Server 效能:檢閱和微調查詢以減少 I/O 需求。 使用索引、避免全表掃描,並解決鎖爭用以提高效率。 使用 最佳做法分析 功能來識別可改善效能的組態選項。
- 請確定防毒排除專案正確:實作 適當的排除專案、在負載下進行測試,以及適當排程掃描,可以降低延遲問題,確保安全性平衡的最佳效能。
I/O 相關最佳做法
由於未正確設定的儲存系統可能會導致效能問題,因此您可以使用 Azure 入口網站中的 [儲存體] 窗格來執行 SQL 最佳做法評量規則的磁碟特定的子集,以識別 Azure VM 上的 SQL Server 的儲存組態問題。 SQL 最佳做法功能基於 SQL 評定 API。
您可以檢視 GitHub 上的建議完整清單。 透過篩選 GitHub 上規則的 id 資料行,您可以查看在 Azure 入口網站中 SQL 虛擬機器資源的 [儲存體] 窗格的 [I/O 組態最佳做法] 索引標籤上驗證的 SQL VM 磁碟組態規則。
- AzSqlVm大小
- AzDataDiskCache
- AzDataDiskStriping
- AzDataOnDataDisks
- AzDb預設位置
- Az磁碟欄位數量
- Azure錯誤日誌位置
- AzPremSsdDataFiles
- AzTempDbFileLocation
- Azure交易日志磁盘缓存
- NTFS 區塊大小未格式化
- 鎖定的頁面在記憶體中
在 [I/O 相關最佳做法] 索引標籤上,使用 [執行評定] 開始評定您的組態,這應該需要幾分鐘的時間才能完成 (除非具有大量資料庫和物件)。 或者,如果您看到最新可用結果的時間戳記,可以使用 [擷取最新結果] 來檢閱先前評定的結果。
使用 PowerShell 分析 I/O
您也可以使用 I/O 分析 PowerShell 指令來分析 SQL Server VM 的 I/O 效能:
# Enter parameters
$subscriptionId = Read-Host "<Subscription ID>"
$resourceGroup = Read-Host "<Resource Group>"
$vmName = Read-Host "<Virtual machine name>"
# Set resource details
$resourceType = "Microsoft.Compute/virtualMachines"
$resourceId = "/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/$resourceType/$vmName"
# Get Azure access token
$accessToken = az account get-access-token --query accessToken -o tsv
# Invoke Azure Monitor Metrics API
function Get-Metrics {
[CmdletBinding()]
param (
[string]$accessToken,
[string]$resourceId,
[string]$metricNames,
[string]$apiVersion = "2023-10-01"
)
try {
$startTime = (Get-Date).AddHours(-24).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ')
$endTime = (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ')
$timespan = "$startTime/$endTime"
Write-Verbose "Evaluating timespan: $timespan"
$uri = "https://management.azure.com$resourceId/providers/Microsoft.Insights/metrics?api-version=$apiVersion&metricnames=$metricNames&aggregation=maximum&interval=PT1M×pan=$timespan"
$headers = @{ "Authorization" = "Bearer $accessToken"; "Content-Type" = "application/json" }
$response = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get
if ($response) {
Write-Verbose "API response successfully retrieved."
return $response
} else {
Write-Error "No response from API."
}
} catch {
Write-Error "Error retrieving metrics: $_"
}
}
# Check if data disk latency violates thresholds
function Check-Latency {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[Object]$metrics,
[Parameter()]
[int]$latencyThreshold = 500,
[Parameter()]
[int]$consecutiveCount = 5
)
$violationTimes = @()
foreach ($metric in $metrics.value) {
if ($metric.name.value -eq "Data Disk Latency") {
$count = 0
foreach ($dataPoint in $metric.timeseries[0].data) {
if ($dataPoint.maximum -gt $latencyThreshold) {
$count++
if ($count -ge $consecutiveCount) {
$violationTimes += $dataPoint.timeStamp
$count = 0 # Reset count after recording a violation
}
} else {
$count = 0 # Reset count if the sequence is broken
}
}
}
}
if ($violationTimes.Count -gt 0) {
Write-Verbose "Latency violations detected."
return @{ "Flag" = $true; "Times" = $violationTimes }
} else {
Write-Verbose "No latency violations detected."
return @{ "Flag" = $false }
}
}
# Check metrics other than latency to evaluate for throttling
function Check-OtherMetricsThrottled {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[Object]$metrics,
[Parameter()]
[int]$PercentageThreshold = 90,
[Parameter()]
[int]$consecutiveCount = 5
)
$violatedMetrics = @()
foreach ($metric in $metrics.value) {
$count = 0
foreach ($dataPoint in $metric.timeseries[0].data) {
if ($dataPoint.maximum -gt $PercentageThreshold) {
$count++
if ($count -ge $consecutiveCount) {
$violatedMetrics += @{ "Metric" = $metric.name.localizedValue; "Time" = $dataPoint.timeStamp; "Value" = $dataPoint.maximum }
break
}
} else {
$count = 0
}
}
}
if ($violatedMetrics.Count -gt 0) {
Write-Verbose "Other metrics violations detected."
} else {
Write-Verbose "No other metrics violations detected."
}
return $violatedMetrics
}
# Compare times for latency & other throttled metrics. Logs the volations with values & timestamps
function CompareTimes {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[Hashtable]$latencyResult,
[Parameter(Mandatory = $true)]
[Array]$otherMetrics
)
foreach ($metric in $otherMetrics) {
$otherDateTime = [DateTime]$metric["Time"]
$isWithinFiveMinutes = $false
$closestLatencyTime = $null
$closestTimeDifference = [int]::MaxValue
foreach ($latencyTime in $latencyResult.Times) {
$latencyDateTime = [DateTime]$latencyTime
$timeDifference = [Math]::Abs(($otherDateTime - $latencyDateTime).TotalMinutes)
if ($timeDifference -le 5) {
$isWithinFiveMinutes = $true
if ($timeDifference -lt $closestTimeDifference) {
$closestTimeDifference = $timeDifference
$closestLatencyTime = $latencyTime
}
}
}
if ($isWithinFiveMinutes) {
if ($otherDateTime -lt $closestLatencyTime) {
Write-Host "`n $($metric["Metric"]) limit was hit before latency spiked at $closestLatencyTime with value $($metric["Value"]). `n"
} else {
Write-Host "`n $($metric["Metric"]) hit its limit with value $($metric["Value"]) at $($metric["Time"])."
Write-Host "Latency spiked at $closestLatencyTime before $($metric["Metric"]) hit its limit `n"
}
} else {
Write-Host "`n Metric: $($metric["Metric"]) exceeded its threshold with a value of $($metric["Value"]) at $($metric["Time"]), but this was not within 5 minutes of any latency spikes."
}
}
}
# Prompt user for latency threshold
$latencyThreshold = Read-Host "Enter Latency Threshold (default is 500)"
if (-not [int]::TryParse($latencyThreshold, [ref]0)) {
$latencyThreshold = 500 # Use default if invalid input
Write-Host "No valid input provided. Using Default 500ms for disk latency threshold"
}
# Execute main logic
$latencyMetrics = Get-Metrics -accessToken $accessToken -resourceId $resourceId -metricNames "Data Disk Latency"
$latencyResult = Check-Latency -metrics $latencyMetrics -latencyThreshold $latencyThreshold
if ($latencyResult.Flag) {
# If latency is flagged, check for other metrics. If there is no disk latency, machine is likely not throttled but only at high consumption
Write-Verbose "Checking the following metrics: Data Disk Bandwidth Consumed Percentage,Data Disk IOPS Consumed Percentage,VM Cached Bandwidth Consumed Percentage,VM Cached IOPS Consumed Percentage,VM Uncached Bandwidth Consumed Percentage,VM Uncached IOPS Consumed Percentage"
$DiskVMMetrics = Get-Metrics -accessToken $accessToken -resourceId $resourceId -metricNames "Data Disk Bandwidth Consumed Percentage,Data Disk IOPS Consumed Percentage,VM Cached Bandwidth Consumed Percentage,VM Cached IOPS Consumed Percentage,VM Uncached Bandwidth Consumed Percentage,VM Uncached IOPS Consumed Percentage"
$additionalMetrics = Check-OtherMetricsThrottled -metrics $DiskVMMetrics
if ($additionalMetrics.Count -gt 0) {
CompareTimes $latencyResult $additionalMetrics
} else {
Write-Host "No metrics violations detected besides latency."
}
} else {
Write-Host "No latency issues detected."
}
下一步
- 執行 SQL 最佳做法評量,以識別可能導致效能問題的潛在組態錯誤。