クラスターのパフォーマンス履歴を取得する
適用対象: Azure Stack HCI、バージョン 23H2 および 22H2。Windows Server 2022、Windows Server 2019
ヘルス サービスにより、記憶域スペース ダイレクト クラスターから現在のパフォーマンスおよび容量の情報を取得するために必要な作業が削減されます。 1 つのコマンドレットにより、厳選された重要なメトリックの一覧が得られます。これらのメトリックは、クラスター メンバーシップを検出する組み込みロジックを使用して複数のノード間で効率的に収集され、動的に集計されます。 値はすべて、リアルタイムかつ特定の時点のみのものです。
PowerShell での使用法
次のコマンドレットを使用し、記憶域スペース ダイレクト クラスター全体のメトリックを取得します。
Get-ClusterPerformanceHistory
ヒント
Get-ClusterPerf エイリアスを使用すると、キーストロークが短縮されます。
また、特定のボリュームやサーバーのメトリックを取得することもできます。
Get-Volume -FileSystemLabel <Label> | Get-ClusterPerformanceHistory
Get-StorageNode -Name <Name> | Get-ClusterPerformanceHistory
.NET および C# での使用方法
このセクションでは、ヘルス サービスに接続し、検出オブジェクトを使用し、およびオブザーバーを実装してメトリックのストリーミングを開始する方法について説明します。
接続する
ヘルス サービスのクエリを実行するには、クラスターと CimSession を確立します。 これを行うには、完全版の Microsoft .NET でのみ使用できるものが必要になります。つまり、Web アプリやモバイル アプリから直接は簡単には実行できません。 このセクションのコード サンプルでは、このデータ アクセス層のための最も単純な選択肢である C# を使用します。
using System.Security;
using Microsoft.Management.Infrastructure;
public CimSession Connect(string Domain = "...", string Computer = "...", string Username = "...", string Password = "...")
{
SecureString PasswordSecureString = new SecureString();
foreach (char c in Password)
{
PasswordSecureString.AppendChar(c);
}
CimCredential Credentials = new CimCredential(
PasswordAuthenticationMechanism.Default, Domain, Username, PasswordSecureString);
WSManSessionOptions SessionOptions = new WSManSessionOptions();
SessionOptions.AddDestinationCredentials(Credentials);
Session = CimSession.Create(Computer, SessionOptions);
return Session;
}
指定するユーザー名は、ターゲット コンピューターのローカル管理者である必要があります。
パスワードがプレーン テキストでメモリに格納されないようにするため、ユーザー入力からパスワードの SecureString をリアルタイムで直接構築することをお勧めします。 これは、さまざまなセキュリティの問題を軽減するために役立ちます。 ただし、実際には、ひな形作成の目的で上記のように構築するのが一般的です。
オブジェクトを検出します
CimSession が確立されると、クラスターで Windows Management Instrumentation (WMI) に対してクエリを実行できます。
障害またはメトリックを取得するには、いくつかの関連オブジェクトのインスタンスを取得する必要があります。 まず、クラスター上の記憶域スペース ダイレクトを表す MSFT_StorageSubSystem を取得します。 それを使用すると、クラスター内のすべての MSFT_StorageNode や、データ ボリュームのすべての MSFT_Volume を取得できます。 最後に、MSCluster_ClusterHealthService (ヘルス サービス自体) を取得する必要があります。
CimInstance Cluster;
List<CimInstance> Nodes;
List<CimInstance> Volumes;
CimInstance HealthService;
public void DiscoverObjects(CimSession Session)
{
// Get MSFT_StorageSubSystem for Storage Spaces Direct
Cluster = Session.QueryInstances(@"root\microsoft\windows\storage", "WQL", "SELECT * FROM MSFT_StorageSubSystem")
.First(Instance => (Instance.CimInstanceProperties["FriendlyName"].Value.ToString()).Contains("Cluster"));
// Get MSFT_StorageNode for each cluster node
Nodes = Session.EnumerateAssociatedInstances(Cluster.CimSystemProperties.Namespace,
Cluster, "MSFT_StorageSubSystemToStorageNode", null, "StorageSubSystem", "StorageNode").ToList();
// Get MSFT_Volumes for each data volume
Volumes = Session.EnumerateAssociatedInstances(Cluster.CimSystemProperties.Namespace,
Cluster, "MSFT_StorageSubSystemToVolume", null, "StorageSubSystem", "Volume").ToList();
// Get MSCluster_ClusterHealthService itself
HealthService = session.QueryInstances(@"root\MSCluster", "WQL", "SELECT * FROM MSCluster_ClusterHealthService").First();
}
これらは、PowerShell で Get-StorageSubSystem、Get-StorageNode、および Get-Volume のようなコマンドレットを使用して取得するものと同じオブジェクトです。
Storage Management API クラスに記載されている、同じプロパティのすべてにアクセスできます。
using System.Diagnostics;
foreach (CimInstance Node in Nodes)
{
// For illustration, write each node's Name to the console. You could also write State (up/down), or anything else!
Debug.WriteLine("Discovered Node " + Node.CimInstanceProperties["Name"].Value.ToString());
}
GetMetric を呼び出して MetricName パラメーターのメトリック名に基づいて、専門家が厳選した重要なメトリックの一覧のストリーミング サンプルを開始します。これは、クラスター メンバーシップを検出するための組み込みロジックを使用して、ノード間で効率的に収集され、動的に集計されます。 サンプルは、StreamName パラメーターから、指定された期間に基づいて到着します。
使用可能なメトリックの全一覧については、「記憶域スペース ダイレクトのパフォーマンス履歴」を参照してください。
IObserver.OnNext()
このサンプル コードでは、オブザーバー デザイン パターンを使用し、メトリックの新しいサンプルが到着するごとに OnNext() メソッドが呼び出されるオブザーバーを実装します。 ストリーミングが終了すると、その OnCompleted() メソッドが呼び出されます。 たとえば、それを使用してストリーミングを再開し、無期限に続行することができます。
class MetricsObserver<T> : IObserver<T>
{
public void OnNext(T Result)
{
// Cast
CimMethodStreamedResult StreamedResult = Result as CimMethodStreamedResult;
if (StreamedResult != null)
{
CimInstance Metric = (CimInstance)StreamedResult.ItemValue;
Console.WriteLine("MetricName: " + Metric.CimInstanceProperties["MetricId"].Value);
IEnumerable<CimInstance> Records = (IEnumerable<CimInstance>)Metric.CimInstanceProperties["Records"].Value;
foreach (CimInstance Record in Records)
{
// Each Record has "TimeStamp" and "Value. For Illustration, just print the metric"
Console.WriteLine(record.CimInstanceProperties["TimeStamp"] + ": " + record.CimInstanceProperties["Value"]);
}
// TODO: Whatever you want!
}
}
public void OnError(Exception e)
{
// Handle Exceptions
}
public void OnCompleted()
{
// Reinvoke BeginStreamingMetrics(), defined in the next section
}
}
ストリーミングを開始する
オブザーバーを定義すると、ストリーミングを開始できます。
メトリックのスコープを設定するターゲットの CimInstance を指定します。 クラスター、任意のノード、または任意のボリュームを指定できます。
count パラメーターは、ストリーミングが終了する前のサンプル数です。
CimInstance Target = Cluster; // From among the objects discovered in DiscoverObjects()
public void BeginStreamingMetrics(CimSession Session, CimInstance HealthService, CimInstance Target)
{
// Set Parameters
CimMethodParametersCollection MetricsParams = new CimMethodParametersCollection();
string[] metricNames = new string[] { "ClusterNode.Cpu.Usage,ClusterNode=RRN44-13-01", "ClusterNode.Cpu.Usage.Host,ClusterNode=RRN44-13-01" };
MetricsParams.Add(CimMethodParameter.Create("MetricName", metricNames, CimType.StringArray, CimFlags.In));
MetricsParams.Add(CimMethodParameter.Create("StreamName", "LastHour", CimType.String, CimFlags.In));
// Enable WMI Streaming
CimOperationOptions Options = new CimOperationOptions();
Options.EnableMethodResultStreaming = true;
// Invoke API
CimAsyncMultipleResults<CimMethodResultBase> InvokeHandler;
InvokeHandler = Session.InvokeMethodAsync(
HealthService.CimSystemProperties.Namespace, HealthService, "GetMetric", MetricsParams, Options
);
// Subscribe the Observer
MetricsObserver<CimMethodResultBase> Observer = new MetricsObserver<CimMethodResultBase>(this);
IDisposable Disposeable = InvokeHandler.Subscribe(Observer);
}
これらのメトリックは、視覚化や、データベースへの格納、または適切と思われるあらゆる方法での使用が可能です。