Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Ve Windows Serveru 2019 zaznamenává Prostory úložiště s přímým přístupem a ukládá rozsáhlou historii výkonu pro virtuální počítače, servery, jednotky, svazky, síťové adaptéry a další. Historie výkonu se v PowerShellu snadno dotazuje a zpracovává, takže můžete rychle přejít z nezpracovaných dat na skutečné odpovědi na otázky, jako jsou:
- Došlo minulý týden ke špičkám využití procesoru?
- Vykazuje nějaký fyzický disk neobvyklou latenci?
- Které virtuální počítače momentálně využívají nejvíce vstupně-výstupních operací za sekundu úložiště?
- Je moje šířka pásma sítě nasycená?
- Kdy na tomto svazku dojde volné místo?
- Které virtuální počítače v minulém měsíci používaly nejvíce paměti?
Cmdlet Get-ClusterPerf je sestavené pro skriptování. Přijímá vstup z rutin, jako jsou Get-VM nebo Get-PhysicalDisk prostřednictvím kanálu pro zpracování asociace, a můžete předat svůj výstup rutina nástrojů, jako je Sort-Object, Where-Object a Measure-Object, abyste rychle sestavit výkonné dotazy.
Toto téma obsahuje a vysvětluje 6 ukázkových skriptů, které odpovídají na 6 výše uvedených otázek. Představují vzory, které můžete použít k vyhledání špiček, hledání průměrů, vykreslení spojnic trendu, zjišťování odlehlé hodnoty a další možnosti v různých datech a časových rámcích. Jsou k dispozici jako bezplatný počáteční kód pro kopírování, rozšiřování a opakované použití.
Note
V zájmu stručnosti ukázkové skripty vynechaly například zpracování chyb, které byste mohli očekávat od vysoce kvalitního kódu PowerShellu. Jsou určeny především pro inspiraci a vzdělávání, nikoli pro produkční použití.
Ukázka 1: CPU, vidím tě!
Tato ukázka používá ClusterNode.Cpu.Usage řadu z LastWeek časového rámce k zobrazení maxima ("horní mez"), minimálního a průměrného využití procesoru pro každý server v clusteru. Provede také jednoduchou kvartilovou analýzu, která ukazuje, kolik hodin bylo využití procesoru vyšší než 25%, 50%a 75% během posledních 8 dní.
Screenshot
Na následujícím snímku obrazovky vidíme, že server-02 měl nevysvětlené špičky minulý týden:
Jak to funguje
Výstup z Get-ClusterPerf potrubí se dobře zapojuje do integrované Measure-Object rutiny a stačí zadat Value vlastnost. S jeho -Maximum, -Minimum, a -Average vlajkami nám Measure-Object dává první tři sloupce skoro zdarma. Abychom mohli provést analýzu kvartilu, můžeme přesměrovat do Where-Object a spočítat, kolik hodnot bylo -Gt (větší než) 25, 50 nebo 75. Posledním krokem je použití pomocných funkcí Format-Hours a Format-Percent k zkrášlení – to je jistě volitelné.
Script
Tady je skript:
Function Format-Hours {
Param (
$RawValue
)
# Weekly timeframe has frequency 15 minutes = 4 points per hour
[Math]::Round($RawValue/4)
}
Function Format-Percent {
Param (
$RawValue
)
[String][Math]::Round($RawValue) + " " + "%"
}
$Output = Get-ClusterNode | ForEach-Object {
$Data = $_ | Get-ClusterPerf -ClusterNodeSeriesName "ClusterNode.Cpu.Usage" -TimeFrame "LastWeek"
$Measure = $Data | Measure-Object -Property Value -Minimum -Maximum -Average
$Min = $Measure.Minimum
$Max = $Measure.Maximum
$Avg = $Measure.Average
[PsCustomObject]@{
"ClusterNode" = $_.Name
"MinCpuObserved" = Format-Percent $Min
"MaxCpuObserved" = Format-Percent $Max
"AvgCpuObserved" = Format-Percent $Avg
"HrsOver25%" = Format-Hours ($Data | Where-Object Value -Gt 25).Length
"HrsOver50%" = Format-Hours ($Data | Where-Object Value -Gt 50).Length
"HrsOver75%" = Format-Hours ($Data | Where-Object Value -Gt 75).Length
}
}
$Output | Sort-Object ClusterNode | Format-Table
Ukázka 2: Požár, požár, výjimka v latenci
Tento vzorek používá PhysicalDisk.Latency.Average řadu z LastHour časového rámce k vyhledání statistických odlehlých hodnot definovaných jako jednotky s hodinovou průměrnou latencí překračující +3σ (tři směrodatné odchylky) nad průměrem základního souboru.
Important
Pro stručnost tento skript neimplementuje ochranu proti nízké odchylkě, nezpracuje částečná chybějící data, nerozlišuje model ani firmware atd. Projděte si dobrý úsudek a nespoléhejte na tento skript sám, abyste zjistili, jestli se má pevný disk nahradit. Je zde prezentován pouze pro vzdělávací účely.
Screenshot
Na následujícím snímku obrazovky vidíme, že neexistují žádné odlehlé hodnoty:
Jak to funguje
Nejprve vyloučíme nečinné nebo téměř nečinné jednotky tím, že ověříme, že PhysicalDisk.Iops.Total je konzistentně -Gt 1. Pro každý aktivní pevný disk předáme svůj LastHour časový rámec, který se skládá z 360 měření v 10sekundových intervalech, abychom Measure-Object -Average získali průměrnou latenci v poslední hodině. To určuje naši populaci.
Implementujeme široce známý vzorec k nalezení střední μ a směrodatné odchylky σ základního souboru. Pro každý aktivní pevný disk porovnáme průměrnou latenci s průměrem základního souboru a vydělíme směrodatnou odchylkou. Surové hodnoty ponecháme, abychom mohli Sort-Object naše výsledky, ale pomocí Format-Latency a Format-StandardDeviation funkcí zkrášlujeme to, co ukážeme – určitě volitelné.
Pokud je nějaký disk větší než +3σ, Write-Host červeně; pokud ne, zeleně.
Script
Tady je skript:
Function Format-Latency {
Param (
$RawValue
)
$i = 0 ; $Labels = ("s", "ms", "μs", "ns") # Petabits, just in case!
Do { $RawValue *= 1000 ; $i++ } While ( $RawValue -Lt 1 )
# Return
[String][Math]::Round($RawValue, 2) + " " + $Labels[$i]
}
Function Format-StandardDeviation {
Param (
$RawValue
)
If ($RawValue -Gt 0) {
$Sign = "+"
}
Else {
$Sign = "-"
}
# Return
$Sign + [String][Math]::Round([Math]::Abs($RawValue), 2) + "σ"
}
$HDD = Get-StorageSubSystem Cluster* | Get-PhysicalDisk | Where-Object MediaType -Eq HDD
$Output = $HDD | ForEach-Object {
$Iops = $_ | Get-ClusterPerf -PhysicalDiskSeriesName "PhysicalDisk.Iops.Total" -TimeFrame "LastHour"
$AvgIops = ($Iops | Measure-Object -Property Value -Average).Average
If ($AvgIops -Gt 1) { # Exclude idle or nearly idle drives
$Latency = $_ | Get-ClusterPerf -PhysicalDiskSeriesName "PhysicalDisk.Latency.Average" -TimeFrame "LastHour"
$AvgLatency = ($Latency | Measure-Object -Property Value -Average).Average
[PsCustomObject]@{
"FriendlyName" = $_.FriendlyName
"SerialNumber" = $_.SerialNumber
"MediaType" = $_.MediaType
"AvgLatencyPopulation" = $null # Set below
"AvgLatencyThisHDD" = Format-Latency $AvgLatency
"RawAvgLatencyThisHDD" = $AvgLatency
"Deviation" = $null # Set below
"RawDeviation" = $null # Set below
}
}
}
If ($Output.Length -Ge 3) { # Minimum population requirement
# Find mean μ and standard deviation σ
$μ = ($Output | Measure-Object -Property RawAvgLatencyThisHDD -Average).Average
$d = $Output | ForEach-Object { ($_.RawAvgLatencyThisHDD - $μ) * ($_.RawAvgLatencyThisHDD - $μ) }
$σ = [Math]::Sqrt(($d | Measure-Object -Sum).Sum / $Output.Length)
$FoundOutlier = $False
$Output | ForEach-Object {
$Deviation = ($_.RawAvgLatencyThisHDD - $μ) / $σ
$_.AvgLatencyPopulation = Format-Latency $μ
$_.Deviation = Format-StandardDeviation $Deviation
$_.RawDeviation = $Deviation
# If distribution is Normal, expect >99% within 3σ
If ($Deviation -Gt 3) {
$FoundOutlier = $True
}
}
If ($FoundOutlier) {
Write-Host -BackgroundColor Black -ForegroundColor Red "Oh no! There's an HDD significantly slower than the others."
}
Else {
Write-Host -BackgroundColor Black -ForegroundColor Green "Good news! No outlier found."
}
$Output | Sort-Object RawDeviation -Descending | Format-Table FriendlyName, SerialNumber, MediaType, AvgLatencyPopulation, AvgLatencyThisHDD, Deviation
}
Else {
Write-Warning "There aren't enough active drives to look for outliers right now."
}
Ukázka 3: Hlučný soused? To je napsat!
Historie výkonu může také odpovídat na otázky týkající se této chvíle. Nová měření jsou k dispozici v reálném čase každých 10 sekund. Tato ukázka používá VHD.Iops.Total řadu z MostRecent časového rámce k identifikaci nejzatíženějších (někteří tomu mohou říkat 'nejhlučnějších') virtuálních počítačů, které využívají nejvíce úložiště IOPS, na každém hostiteli v clusteru, a zobrazuje rozpis jejich aktivity čtení a zápisu.
Screenshot
Na následujícím snímku obrazovky vidíme prvních 10 virtuálních počítačů podle aktivity úložiště:
Jak to funguje
Na rozdíl od Get-PhysicalDiskrutiny Get-VM nerozlišuje cluster – vrací pouze virtuální počítače na místním serveru. K paralelnímu dotazování z každého serveru zabalíme volání do Invoke-Command (Get-ClusterNode).Name { ... }. Pro každý virtuální počítač získáme VHD.Iops.Total, VHD.Iops.Read, a VHD.Iops.Write měření. Nepřenesením parametru -TimeFrame získáme MostRecent jeden datový bod pro každý.
Tip
Tyto série odrážejí celkovou aktivitu tohoto virtuálního počítače na všechny jeho soubory VHD/VHDX. Toto je příklad, kdy se pro nás automaticky agreguje historie výkonu. Pokud chcete získat rozpis jednotlivých disků VHD/VHDX, můžete jednotlivý Get-VHD nasměrovat do Get-ClusterPerf místo virtuálního počítače.
Výsledky z každého serveru se spojují jako $Output, což můžeme Sort-Object a poté Select-Object -First 10. Všimněte si, že Invoke-Command zdobí výsledky PsComputerName vlastností, která označuje, odkud pocházejí, kterou můžeme vytisknout, abychom věděli, kde je virtuální počítač spuštěný.
Script
Tady je skript:
$Output = Invoke-Command (Get-ClusterNode).Name {
Function Format-Iops {
Param (
$RawValue
)
$i = 0 ; $Labels = (" ", "K", "M", "B", "T") # Thousands, millions, billions, trillions...
Do { if($RawValue -Gt 1000){$RawValue /= 1000 ; $i++ } } While ( $RawValue -Gt 1000 )
# Return
[String][Math]::Round($RawValue) + " " + $Labels[$i]
}
Get-VM | ForEach-Object {
$IopsTotal = $_ | Get-ClusterPerf -VMSeriesName "VHD.Iops.Total"
$IopsRead = $_ | Get-ClusterPerf -VMSeriesName "VHD.Iops.Read"
$IopsWrite = $_ | Get-ClusterPerf -VMSeriesName "VHD.Iops.Write"
[PsCustomObject]@{
"VM" = $_.Name
"IopsTotal" = Format-Iops $IopsTotal.Value
"IopsRead" = Format-Iops $IopsRead.Value
"IopsWrite" = Format-Iops $IopsWrite.Value
"RawIopsTotal" = $IopsTotal.Value # For sorting...
}
}
}
$Output | Sort-Object RawIopsTotal -Descending | Select-Object -First 10 | Format-Table PsComputerName, VM, IopsTotal, IopsRead, IopsWrite
Ukázka 4: Jak říkají, "25-gig je nový 10-gig"
Tato ukázka používá NetAdapter.Bandwidth.Total řadu z LastDay časového rámce k vyhledání známek sytosti sítě definované jako >90% teoreticky maximální šířky pásma. U každého síťového adaptéru v clusteru porovnává nejvyšší pozorované využití šířky pásma za poslední den s uvedenou rychlostí propojení.
Screenshot
Na následujícím snímku obrazovky vidíme, že jeden Fabrikam NX-4 Pro č. 2 dosáhl vrcholu za poslední den.
Jak to funguje
Zopakujeme náš Invoke-Command trik ze shora na všechny servery a přesměrujeme do Get-NetAdapter. Na cestě vezmeme dvě relevantní vlastnosti: její LinkSpeed řetězec jako "10 Gb/s" a jeho nezpracované Speed celé číslo, jako je 10000000000. Používáme Measure-Object k získání průměru a špičky z posledního dne (připomenutí: každé měření v LastDay časovém rámci představuje 5 minut) a vynásobíme 8 bity na bajt, abychom získali spravedlivé porovnání.
Note
Někteří dodavatelé, například Chelsio, zahrnují aktivitu vzdáleného přímého přístupu do paměti (RDMA) do čítačů výkonu síťových adaptérů , takže je součástí NetAdapter.Bandwidth.Total řady. Jiní, jako Mellanox, možná ne. Pokud váš dodavatel neposkytuje, jednoduše přidejte NetAdapter.Bandwidth.RDMA.Total sérii do své verze tohoto skriptu.
Script
Tady je skript:
$Output = Invoke-Command (Get-ClusterNode).Name {
Function Format-BitsPerSec {
Param (
$RawValue
)
$i = 0 ; $Labels = ("bps", "kbps", "Mbps", "Gbps", "Tbps", "Pbps") # Petabits, just in case!
Do { $RawValue /= 1000 ; $i++ } While ( $RawValue -Gt 1000 )
# Return
[String][Math]::Round($RawValue) + " " + $Labels[$i]
}
Get-NetAdapter | ForEach-Object {
$Inbound = $_ | Get-ClusterPerf -NetAdapterSeriesName "NetAdapter.Bandwidth.Inbound" -TimeFrame "LastDay"
$Outbound = $_ | Get-ClusterPerf -NetAdapterSeriesName "NetAdapter.Bandwidth.Outbound" -TimeFrame "LastDay"
If ($Inbound -Or $Outbound) {
$InterfaceDescription = $_.InterfaceDescription
$LinkSpeed = $_.LinkSpeed
$MeasureInbound = $Inbound | Measure-Object -Property Value -Maximum
$MaxInbound = $MeasureInbound.Maximum * 8 # Multiply to bits/sec
$MeasureOutbound = $Outbound | Measure-Object -Property Value -Maximum
$MaxOutbound = $MeasureOutbound.Maximum * 8 # Multiply to bits/sec
$Saturated = $False
# Speed property is Int, e.g. 10000000000
If (($MaxInbound -Gt (0.90 * $_.Speed)) -Or ($MaxOutbound -Gt (0.90 * $_.Speed))) {
$Saturated = $True
Write-Warning "In the last day, adapter '$InterfaceDescription' on server '$Env:ComputerName' exceeded 90% of its '$LinkSpeed' theoretical maximum bandwidth. In general, network saturation leads to higher latency and diminished reliability. Not good!"
}
[PsCustomObject]@{
"NetAdapter" = $InterfaceDescription
"LinkSpeed" = $LinkSpeed
"MaxInbound" = Format-BitsPerSec $MaxInbound
"MaxOutbound" = Format-BitsPerSec $MaxOutbound
"Saturated" = $Saturated
}
}
}
}
$Output | Sort-Object PsComputerName, InterfaceDescription | Format-Table PsComputerName, NetAdapter, LinkSpeed, MaxInbound, MaxOutbound, Saturated
Ukázka 5: Opět vytvořte trendy úložiště!
Pokud se chcete podívat na makrotrendy, historie výkonu se uchovává po dobu až 1 roku. Tato ukázka používá Volume.Size.Available řadu z LastYear časového rámce k určení rychlosti, kterou úložiště zaplňuje, a odhadne, kdy se zaplní.
Screenshot
Na následujícím snímku obrazovky vidíme, že svazek zálohování přidává přibližně 15 GB za den:
V této míře dosáhne své kapacity za dalších 42 dnů.
Jak to funguje
Časový LastYear rámec má jeden datový bod za den. I když k přizpůsobení spojnice trendu potřebujete pouze dva body, v praxi je lepší vyžadovat více, například 14 dní. Používáme Select-Object -Last 14 k nastavení pole bodů (x, y) pro x v rozsahu [1, 14]. S těmito body implementujeme jednoduchý algoritmus lineárních nejmenších čtverců, abychom našli $A a $B, které parametrizují čáru nejlepšího přizpůsobení y = ax + b. Vítejte na střední škole znovu.
Dělením vlastnosti objemu SizeRemaining trendem (sklon $A) můžeme hrubě odhadnout, za kolik dní se při současném tempu růstu úložiště objem zaplní. Pomocné funkce Format-Bytes, Format-Trend a Format-Days zkrášlují výstup.
Important
Tento odhad je lineární a vychází pouze z posledních 14 denních měření. Existují sofistikovanější a přesnější techniky. Projděte si dobrý úsudek a nespoléhejte na tento skript sám, abyste zjistili, jestli investovat do rozšiřování úložiště. Je zde prezentován pouze pro vzdělávací účely.
Script
Tady je skript:
Function Format-Bytes {
Param (
$RawValue
)
$i = 0 ; $Labels = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
Do { $RawValue /= 1024 ; $i++ } While ( $RawValue -Gt 1024 )
# Return
[String][Math]::Round($RawValue) + " " + $Labels[$i]
}
Function Format-Trend {
Param (
$RawValue
)
If ($RawValue -Eq 0) {
"0"
}
Else {
If ($RawValue -Gt 0) {
$Sign = "+"
}
Else {
$Sign = "-"
}
# Return
$Sign + $(Format-Bytes ([Math]::Abs($RawValue))) + "/day"
}
}
Function Format-Days {
Param (
$RawValue
)
[Math]::Round($RawValue)
}
$CSV = Get-Volume | Where-Object FileSystem -Like "*CSV*"
$Output = $CSV | ForEach-Object {
$N = 14 # Require 14 days of history
$Data = $_ | Get-ClusterPerf -VolumeSeriesName "Volume.Size.Available" -TimeFrame "LastYear" | Sort-Object Time | Select-Object -Last $N
If ($Data.Length -Ge $N) {
# Last N days as (x, y) points
$PointsXY = @()
1..$N | ForEach-Object {
$PointsXY += [PsCustomObject]@{ "X" = $_ ; "Y" = $Data[$_-1].Value }
}
# Linear (y = ax + b) least squares algorithm
$MeanX = ($PointsXY | Measure-Object -Property X -Average).Average
$MeanY = ($PointsXY | Measure-Object -Property Y -Average).Average
$XX = $PointsXY | ForEach-Object { $_.X * $_.X }
$XY = $PointsXY | ForEach-Object { $_.X * $_.Y }
$SSXX = ($XX | Measure-Object -Sum).Sum - $N * $MeanX * $MeanX
$SSXY = ($XY | Measure-Object -Sum).Sum - $N * $MeanX * $MeanY
$A = ($SSXY / $SSXX)
$B = ($MeanY - $A * $MeanX)
$RawTrend = -$A # Flip to get daily increase in Used (vs decrease in Remaining)
$Trend = Format-Trend $RawTrend
If ($RawTrend -Gt 0) {
$DaysToFull = Format-Days ($_.SizeRemaining / $RawTrend)
}
Else {
$DaysToFull = "-"
}
}
Else {
$Trend = "InsufficientHistory"
$DaysToFull = "-"
}
[PsCustomObject]@{
"Volume" = $_.FileSystemLabel
"Size" = Format-Bytes ($_.Size)
"Used" = Format-Bytes ($_.Size - $_.SizeRemaining)
"Trend" = $Trend
"DaysToFull" = $DaysToFull
}
}
$Output | Format-Table
Ukázka 6: Žrout paměti, můžete běžet, ale nemůžete se skrýt.
Vzhledem k tomu, že se historie výkonu shromažďuje a ukládá centrálně pro celý cluster, nemusíte spojovat data z různých počítačů bez ohledu na to, kolikrát se virtuální počítače pohybují mezi hostiteli. Tato ukázka používá VM.Memory.Assigned řadu z LastMonth časového rámce k identifikaci virtuálních počítačů, které spotřebovávají nejvíce paměti za posledních 35 dnů.
Screenshot
Na následujícím snímku obrazovky vidíme prvních 10 virtuálních počítačů podle využití paměti za poslední měsíc:
Jak to funguje
Opakujeme náš Invoke-Command trik, který jsme představili výše, na Get-VM každém serveru. Použijeme Measure-Object -Average k získání měsíčního průměru pro každý virtuální počítač a následně Sort-ObjectSelect-Object -First 10 získáme tabulku výsledků. (Nebo možná je to náš seznam Most Wanted ?)
Script
Tady je skript:
$Output = Invoke-Command (Get-ClusterNode).Name {
Function Format-Bytes {
Param (
$RawValue
)
$i = 0 ; $Labels = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
Do { if( $RawValue -Gt 1024 ){ $RawValue /= 1024 ; $i++ } } While ( $RawValue -Gt 1024 )
# Return
[String][Math]::Round($RawValue) + " " + $Labels[$i]
}
Get-VM | ForEach-Object {
$Data = $_ | Get-ClusterPerf -VMSeriesName "VM.Memory.Assigned" -TimeFrame "LastMonth"
If ($Data) {
$AvgMemoryUsage = ($Data | Measure-Object -Property Value -Average).Average
[PsCustomObject]@{
"VM" = $_.Name
"AvgMemoryUsage" = Format-Bytes $AvgMemoryUsage.Value
"RawAvgMemoryUsage" = $AvgMemoryUsage.Value # For sorting...
}
}
}
}
$Output | Sort-Object RawAvgMemoryUsage -Descending | Select-Object -First 10 | Format-Table PsComputerName, VM, AvgMemoryUsage
To je to! Snad vás tyto ukázky inspirují a pomohou vám začít. Díky historii výkonu Storage Spaces Direct a mocné rutině pro skriptování můžete klást otázky – a odpovídat na ně! – složité otázky při správě a monitorování infrastruktury Windows Serveru 2019.