StreamInsight サーバーの概念
このトピックでは、StreamInsight サーバーにおけるデータの表現、処理、受信、および送信の方法について説明します。その目的は Microsoft StreamInsight の複雑なイベント処理に関連する基本概念を理解することです。ここでは、まず、データ構造について説明してから、データを操作または処理する StreamInsight サーバー コンポーネントについて説明します。
ストリーム
StreamInsight のすべてのデータはストリームとして形成されます。各ストリームは、時間の経過と共に変化するデータのコレクション (終了しない場合もあります) を表します。たとえば、株式ティッカー ストリームは時間と共に変化する株式市場での株価を示し、温度センサー ストリームは時間と共に変化する、センサーから報告される温度値を示します。
電力監視のシナリオを考えてみます。このシナリオでは、さまざまなデバイスの電力消費量を測定する、一連の電力メーターを監視することを目的としています。これらの電力メーターからは、定期的に、データが送信されます。このデータには、電力消費量 (ワットの 10 分の 1 単位) や測定値の関連したタイム スタンプが含まれます。次の表に 3 つのメーターの電力測定値を示します。また、ここでは、各電力メーターが電力測定値を毎秒出力するとします。
時刻 |
MeterID |
消費量 |
---|---|---|
2009-07-27 10:27:23 |
1 |
100 |
2009-07-27 10:27:24 |
1 |
200 |
2009-07-27 10:27:51 |
2 |
300 |
2009-07-27 10:28:52 |
2 |
100 |
2009-07-27 10:27:23 |
3 |
200 |
この情報は時間の経過と共に変化する値として表すことができるため、データをストリームで表すことができます。このストリームのデータに対してクエリを実行すると、特定の期間における消費電力の最高値と最低値を示すメーターや、一定の期間において電力消費の高い方から上位 10 個のメーター一覧を返すことができます。
イベント
ストリームに表示される基になるデータは、イベントとしてパッケージ化されます。イベントとは、StreamInsight サーバーで処理されるデータの基本単位です。各イベントの構成要素は次のとおりです。
ヘッダー。各イベント ヘッダーには、イベントの種類を定義するメタデータと、イベントの期間を定義する 1 つ以上のタイムスタンプが含まれます。タイムスタンプは、アプリケーションベースであり、StreamInsight サーバーで指定されたシステム時刻ではなくデータ ソースによって指定されます。タイムスタンプには、DateTimeOffset データ型が使用されることに注意してください。このデータ型では、タイム ゾーンに対応した 24 時間形式の時刻が提供されます。StreamInsight サーバーではすべての時刻が UTC 日時に正規化され、入力時には、タイムスタンプ フィールドに UTC フラグが設定されているかどうかが検証されます。
ペイロード。イベントに関連付けられたデータが格納される .NET データ構造です。ペイロードで定義されるフィールドは、ユーザー定義フィールドです。このフィールドの種類は .NET 型システムに基づいています。
ストリーム内のイベントのアプリケーション タイムスタンプがクエリへの到着順に対応している場合は、イベントが "順序どおり" であると言います。対応していない場合は、イベントが "順序不定" であると言います。StreamInsight サーバーでは、クエリで明示的に指定されていない限り、イベントが順序不定で到着した場合でも、クエリの出力は、イベントが順序どおりに到着した場合と同じになります。ストリーム内での典型的なイベント到着パターンを次に示します。
ファイルやテーブルのレコードなど、安定した速度。
小売店のバーコード スキャナーからのデータなど、断続的でランダムな速度。
Web クリックや気象遠隔測定など、突発性を伴う断続的な速度。
イベント ヘッダー
イベントのヘッダーでは、イベントの種類に加え、イベントの一時プロパティも定義します。
イベントの種類
イベントの種類は、イベントがストリーム内の新しいイベントであるかどうかや、ストリーム内の既存のイベントの完全性を宣言しているかどうかを示します。StreamInsight では、INSERT および CTI (Current Time Increment) という 2 つのイベントの種類がサポートされます。
INSERT イベントでは、イベントがそのペイロードと共にイベント ストリームに追加されます。ペイロードに加え、INSERT イベントのヘッダーでは、イベントの開始時刻と終了時刻が特定されます。次の表に、INSERT イベントのレイアウトを示します。
ヘッダー |
ペイロード |
---|---|
Event kind ::= INSERT StartTime ::= DateTimeOffset EndTime ::= DateTimeOffset |
Field 1 … Field n as CLR types |
CTI イベントは、ストリーム内の既存のイベントの完全性を示す特殊な中断イベントです。CTI のイベント構造は、現在のタイムスタンプを示す 1 つのフィールドで構成されています。CTI イベントは 2 つの目的で使用されます。
1 番目の目的は、アプリケーション タイムスタンプがクエリへのイベントの到着順に対応していないイベントをクエリが受け取り、処理できるようにすることです。CTI イベントの発生は、StreamInsight サーバーに対して、これ以降に受信する INSERT イベントによって CTI タイムスタンプより前のイベント履歴が変更されないことを示します。つまり CTI イベントが発行された場合、それ以降は、INSERT イベントの開始時刻が CTI イベントのタイムスタンプより前になることはありません。イベントのストリームの完全性を示すことにより、StreamInsight サーバーは、状態を累積しているウィンドウ演算子などの集計演算子の結果を解放できるため、システム全体のイベント フローが効率的になります。
CTI イベントの 2 番目の目的は、クエリの低待機時間を維持することです。CTI を頻繁に発行することで、クエリはより頻繁に結果を出力できます。
重要 |
---|
入力ストリームに CTI イベントが含まれていないと、クエリの結果は生成されません。 |
詳細については、「先行するアプリケーション時間」を参照してください。
次の表に、CTI イベントのレイアウトを示します。
ヘッダー |
---|
Event kind ::= CTI StartTime ::= DateTimeOffset |
イベント モデル
イベント モデルでは、一時的な特性に基づいてイベントの状態を定義します。StreamInsight では、期間、ポイント、境界という 3 つのイベント モデルがサポートされています。最も一般的な種類と言えるのは期間イベントで、境界とポイントは特別なケースです。
期間
期間イベント モデルは、ペイロードが一定期間有効なイベントを表します。間隔イベント モデルでは、イベント メタデータでイベントの開始時刻と終了時刻の両方を指定する必要があります。期間イベントが有効なのは、この特定の期間のみです。イベントのペイロードの有効性に関して、開始時刻は含まれるのに対し、終了時刻は含まれないことに注意する必要があります。
次の表に、期間イベント モデルのレイアウトを示します。
メタデータ |
ペイロード |
---|---|
Event kind ::= INSERT StartTime ::= DateTimeOffset EndTime ::= DateTimeOffset |
Field 1 … Field n as CLR types |
期間イベントの例として、電子パルス幅やオークション入札期間 (有効期限) のほか、特定期間の間、株式の指値が有効になるストック ティッカー アクティビティなどがあります。既に説明した電力監視の例では、電力メーターのイベント ストリームを次の期間イベントで表すことができます。
イベントの種類 |
開始 |
終了 |
ペイロード (消費量) |
---|---|---|---|
INSERT |
2009-07-15 09:13:33.317 |
2009-07-15 09:14:09.270 |
100 |
INSERT |
2009-07-15 09:14:09.270 |
2009-07-15 09:14:22.255 |
200 |
INSERT |
2009-07-15 09:14:22.255 |
2009-07-15 09:15:04.987 |
100 |
ポイント
ポイント イベント モデルは、ある時点におけるイベントの発生を表します。ポイント イベント モデルでは、イベントの開始時刻のみが必要になります。StreamInsight サーバーは、開始時刻にチック (基になる時刻データ型における時間の最小単位) を追加することによって有効な終了時刻を推測し、イベントに有効な期間を設定します。イベントの終了時刻は含まれないことから、ポイント イベントは、1 つの時点 (開始時刻) でのみ有効になります。
次の表に、ポイント イベント モデルのレイアウトを示します。
メタデータ |
ペイロード |
---|---|
Event kind ::= INSERT StartTime ::= DateTimeOffset |
Field 1 … Field n as CLR types |
ポイント イベントの例として、メーター値の読み取り、電子メールの到着、ユーザーによる Web クリック、株価の変化、または Windows イベント ログへのエントリがあります。既に説明した電力監視の例では、電力メーターのイベント ストリームを次のポイント イベントで表すことができます。終了時刻は開始時刻に 1 チック (t) を加えて計算されます。
イベントの種類 |
開始 |
終了 |
ペイロード (消費量) |
---|---|---|---|
INSERT |
2009-07-15 09:13:33.317 |
2009-07-15 09:13:33.317 + t |
100 |
INSERT |
2009-07-15 09:14:09.270 |
2009-07-15 09:14:09.270 + t |
200 |
INSERT |
2009-07-15 09:14:22.255 |
2009-07-15 09:14:22.255 + t |
100 |
境界
境界イベント モデルは、ペイロードが一定期間有効なイベント発生を表しますが、StreamInsight サーバーに到着したときにわかるのは開始時刻だけです。終了時刻は、将来の時刻の最大値に設定されます。イベントの終了時刻は後で判明し、更新されます。境界イベント モデルには発生時刻と境界の種類という 2 つのプロパティがあります。これらのプロパティを共に使用して、境界イベントの開始点または終了点を定義します。
次の表に、境界イベント モデルのレイアウトを示します。
メタデータ |
ペイロード |
---|---|
Event kind ::= INSERT Edge time ::= DateTimeOffset Edge type ::= START | END |
Field 1 … Field n as CLR types |
境界イベントの例として、Windows プロセス、Event Tracing for Windows (ETW) からのトレース イベント、Web ユーザー セッション、アナログ信号の量子化などがあります。境界イベントのペイロードの有効な時間間隔は、Start イベントのタイムスタンプと End イベントのタイムスタンプの差になります。次の図では、ペイロード値 'c' のイベントの終了日がこの時点では不明であることに注意してください。
イベントの種類 |
境界の種類 |
開始時刻 |
終了時刻 |
ペイロード |
---|---|---|---|---|
INSERT |
Start |
t0 |
DateTimeOffset.MaxValue |
a |
INSERT |
End |
t0 |
t1 |
a |
INSERT |
Start |
t1 |
DateTimeOffset.MaxValue |
b |
INSERT |
End |
t1 |
t3 |
b |
INSERT |
Start |
t3 |
DateTimeOffset.MaxValue |
c |
… |
次の図に、上記の表で定義されている開始時刻と終了時刻に基づいた境界イベントを使用したアナログ信号の量子化を示します。このような連続した信号は、それぞれ新しい値の END 境界と START 境界の両方が送信される必要があることを意味しています。図で説明している境界は、時刻 t1 から t3 までのイベントを示しています。
イベント モデルの選択に関連するパフォーマンスの考慮事項
問題に適したイベント モデルを選択することが重要です。たとえば、イベントに一定の有効期間があり、アプリケーションでイベントの開始時刻と終了時刻の両方を特定できる場合は、期間イベントを使用してモデル化するのが適しています。イベントが到着した時点ではイベントの終了時刻がわからない場合は、イベントをポイント イベントとしてモデル化し、一定の有効期間を持つように有効期間を変更して、イベントの終了時刻がわかったらクリップ操作を使用して有効期間を変更することができます。その他に、エッジ イベントとしてモデル化するという選択肢もあります。
エッジ イベントは非常に便利なイベント モデルですが、注意する必要があるパフォーマンス上の問題がいくつかあります。エッジ イベントの処理は、イベントが完全な順序 (すべての開始エッジと終了エッジが開始時刻順および終了時刻順に並んでいて、両方を組み合わせたイベントのシーケンスも時間順に並んでいる状態) で到着した場合に最もパフォーマンスが高くなります。たとえば、次のようなエッジ イベントのシーケンスがあったとします。
イベントの種類 |
境界の種類 |
開始時刻 |
終了時刻 |
ペイロード |
INSERT |
Start |
1 |
DateTimeOffset.MaxValue |
a |
INSERT |
End |
1 |
10 |
a |
INSERT |
Start |
3 |
DateTimeOffset.MaxValue |
b |
INSERT |
End |
3 |
6 |
b |
INSERT |
Start |
5 |
DateTimeOffset.MaxValue |
c |
INSERT |
End |
5 |
20 |
c |
このシーケンスはタイムスタンプ順になっていません (1、10、3、6、5、20)。これらのエッジ イベントが完全な順序 (1、3、5、6、10、20) になっていた場合、クエリの処理に対するパフォーマンスの影響は小さくなります。処理の前にこのような並べ替えを行うのは簡単です。問題を 2 つのクエリに分割し、1 つ目のクエリは、エッジ イベントを入力として受け取り、完全な順序に並べ替えて、並べ替え済みのエッジ イベントを出力する空のクエリとし、2 つ目のクエリでその入力を受け取って、メイン ロジックを実行します。これらのクエリは、2 つの別のクエリとして定義して、動的なクエリ構成を使用して結合する必要があります。詳細については、「実行時のクエリの構築」を参照してください。
イベント ペイロード
イベントのペイロードとは、イベントに関連付けられたデータが格納される .NET データ構造のことです。ペイロード内のフィールドはユーザーが定義し、その型は .NET 型システムに基づいています。ペイロード フィールドでは、ほとんどの CLR のスカラー型および基本型がサポートされています。入れ子になった型はサポートされません。
アダプター
アダプターは、StreamInsight サーバーが受信または送信するイベント ストリームの変換および配信を行います。StreamInsight に用意されている柔軟性の高いアダプター SDK を使用すると、ドメイン固有のイベント ソースおよび出力デバイス (シンク) 用のアダプターを構築できます。アダプターは C# プログラミング言語を使用して実装され、アセンブリとして格納されます。アダプター クラスはデザイン時にテンプレートとして作成され、StreamInsight サーバーに登録されて、アダプター インスタンスとして実行時にサーバーでインスタンス化されます。
入力アダプター
入力アダプター インスタンスでは、データベース、ファイル、ティッカー フィード、ネットワーク ポート、センサーなどの外部ソースから受信したイベント ストリームを受け取ります。入力アダプターは、指定された形式で受信イベントを読み取り、StreamInsight サーバーで使用できるイベント形式にこのデータを変換します。
入力アダプターは、データ ソース固有のイベント ソースを処理するために作成されます。イベント ソースが生成するイベントの種類が 1 つのみの場合は、アダプターを型指定できます。つまり、そのアダプターを実装して特定の種類のイベントを生成することができます。型指定されたアダプターでは、アダプターのすべてのインスタンスによって、フィールドの数と種類が事前にわかっている、同一の固定ペイロード形式が生成されます。このようなイベントの例として、ティッカー フィード データや、特定のデバイスから出力されるセンサー データがあります。イベント ソースから状況に応じて異なる型が出力される場合、つまり、イベントにさまざまなペイロード形式が含まれていたり、ペイロード形式が事前にわからない場合は、アダプターを型指定しないで実装してください。型指定しない (汎用の) アダプターの場合、イベントのペイロード形式は、クエリ バインド時に構成の仕様の一部として、アダプターに提供されます。このようなソースの例には、さまざまな数のフィールドを含む CSV ファイル (ファイルに格納されているデータの型はクエリがインスタンス化されるまで不明) や、SQL Server テーブルのアダプター (生成されるイベントはテーブルのスキーマに応じて異なる) があります。重要なのは、型指定されているかどうかに関係なく 1 つのアダプター インスタンスが、常に特定の種類のイベントを実行時に生成することです。型指定されていないアダプターでは、アダプターの実装時にイベントの種類を定義するのではなく、クエリ バインド時にイベントの種類の仕様を受け入れるように柔軟な実装を提供します。
出力アダプター
出力アダプターは、StreamInsight サーバーによって処理されたイベントを受け取り、そのイベントを出力デバイス (シンク) が必要とする形式に変換して、データをそのデバイスに出力するために作成します。出力アダプターのデザインと作成は、入力アダプターのデザインと作成と同じように行います。型指定された出力アダプターは特定のイベント ペイロードに対して設計されています。一方、型指定されていない出力アダプターには、クエリがインスタンス化されるとき実行時にのみイベントの種類が指定されます。
詳細については、「入力アダプターと出力アダプターの作成」を参照してください。コア アダプター API は、あらゆるイベント ソースやイベント シンクの実装に対応する最大限の柔軟性を備えています。また、StreamInsight では、IObservable インターフェイスや IEnumerable インターフェイスを実装するより抽象レベルの高いイベント ソースやイベント シンクもサポートされています。詳細については、「監視可能なイベント ソース/シンクと列挙可能なイベント ソース/シンクの使用 (StreamInsight)」を参照してください。
イベントの処理と分析
StreamInsight を使用すると、定義するクエリ ロジックに基づいて、イベント処理がクエリとして形成されます。このようなクエリでは、時間が区別される入力データ (ログに記録されたデータまたはリアル タイムのデータ) のフィードを受け取り (フィードは無限の場合もある)、そのデータに対して計算を実行して、結果を適切に出力します。
クエリ テンプレート
クエリ テンプレートは、クエリ構成の基本単位です。クエリ テンプレートは、入力アダプターから StreamInsight サーバーに送信されたイベントを連続的に分析および処理し、出力アダプターによって使用されるイベント ストリームを生成するために必要なビジネス ロジックを定義する構造になっています。たとえば、特定の期間に、設定した特定のしきい値を超える最大値と最小値について、電力消費量に関する受信イベントを評価できます。
クエリ テンプレートは、特定の作業単位を実行するように作成してから、組み合わせによってより複雑なクエリ テンプレートにすることができます。クエリ テンプレートは、C# 言語と LINQ を組み合わせて作成します。LINQ とは、ホスト言語に完全に統合された方法で、集合に対する宣言型の計算を表現するための言語プラットフォームです。これにより、同じ開発プラットフォームで、宣言型のイベント処理に、手続き型のプログラミングによる柔軟性を組み合わせることができます。その際、これら 2 つのプログラミング パラダイム間のインピーダンス ミスマッチを心配する必要はありません。
StreamInsight サーバーには、優れたクエリと分析を実施するために次の機能が用意されています。
追加イベント プロパティを使用した計算
単位変換などの使用例では、受け取ったイベントに対して計算を実行する必要があります。StreamInsight サーバーで射影演算を使用すると、ペイロードにフィールドを追加して、入力イベントのフィールドに対して計算を実行できます。詳細については、「射影」を参照してください。
イベントのフィルター処理
警告通知などの使用例では、特定のペイロード フィールドが、監視対象の機器の動作のしきい値を超えているかどうかを調べる場合があります。一般に、このような使用例には、特定の特性に当てはまるイベントのサブセットのみが関連します。こうした特性を持たないイベントは処理する必要がないため、破棄できます。フィルター操作を使用すると、イベント ペイロードに対してブール述語を記述し、述語に適合しないイベントを破棄できます。詳細については、「フィルター」を参照してください。
イベントのグループ化
すべての温度センサーから温度を読み取ることができるイベント ストリームを考えてみます。すべてのイベントが単一のイベント ストリームから提供される場合、センサーの場所またはセンサー ID に基づいて受信イベントを分割できます。StreamInsight サーバーでは、グループ化操作を実行できます。これにより、場所や ID などのイベント プロパティに基づいて受信ストリームを分割してから、各グループに対して別々に他の操作を適用したり、クエリ フラグメントを実行したりできます。詳細については、「グループ化と適用」を参照してください。
ウィンドウの推移
時間に沿ったイベントのグループ化は、多くのシナリオを実現する強力な概念です。たとえば、一定の期間に派生した障害の数を調べて、しきい値を超えた場合に警告を生成する場合があります。ホッピング ウィンドウとスライディング ウィンドウを使用すると、イベント ストリーム全体のウィンドウを定義して、このような分析を実行することができます。詳細については、「イベント ウィンドウの使用」を参照してください。
集計
個々のイベントに注意する必要がない場合は、平均、総計、件数などの集計値に注目することができます。StreamInsight サーバーには、通常は期間に対して適用される、sum、count、min、max、average 用の組み込み集計が用意されています。詳細については、「集計」を参照してください。
上位 N 個の候補の特定
特定の基準に基づいてイベント ストリームで最高順位になる候補イベントを指定する場合は、特殊な集計操作が必要になります。TopK 演算を使用すると、ストリームのイベント フィールドに対して設定した順序に基づいてこれらを調べることができます。詳細については、「TopK」を参照してください。
異なるストリームのイベントの照合
一般的な使用例として、複数のストリームから受け取ったイベントを理論的に判断する必要性があります。たとえば、イベント ソースによってそのイベント データにタイムスタンプが提供されるため、イベントどうしの時間が密接に関係している場合のみ、あるストリーム内のイベントと 2 番目のストリーム内のイベントとの照合を行うようにします。さらに、照合するイベントおよび照合するタイミングに関する制約を追加することもできます。StreamInsight サーバーには、2 つのタスクを実行する強力な結合操作が用意されています。最初のタスクでは、2 つのソースの時間が重複する場合にそのソースのイベントを照合します。次のタスクでは、ペイロード フィールドに指定された結合述語を実行します。このような照合の結果には、最初のイベントと 2 番目のイベント両方のペイロードが含まれます。詳細については、「結合」を参照してください。
異なるストリームのイベントの結合
複数のデータ ソースには、同じクエリに使用する、同じ種類のイベントが用意されている場合があります。StreamInsight サーバーに用意されている和集合演算を使用すると、複数の入力ストリームを 1 つの出力ストリームに多重送信することができます。詳細については、「和集合」を参照してください。
ユーザー定義の拡張機能
StreamInsight サーバーの組み込みのクエリ機能は、どのような場合にも十分であるとは限りません。ドメイン固有の拡張機能を許可するために、StreamInsight サーバーのクエリでは、.NET アセンブリによって提供されるユーザー定義の機能を呼び出すことができます。ユーザー定義関数のほかに、カスタム集計やクエリ演算子を定義して実装することもできます。詳細については、「ユーザー定義関数」および「ユーザー定義の集計と演算子」を参照してください。
詳細については、「LINQ でのクエリ テンプレートの記述」を参照してください。StreamInsight の LINQ クエリの記述方法については、「A Hitchhiker's Guide to StreamInsight Queries」を参照してください。
クエリ インスタンス
クエリ テンプレートを特定の入出力アダプターにバインドすると、StreamInsight サーバーにクエリ インスタンスが登録されます。バインド クエリは、StreamInsight サーバーで開始、停止、および管理できます。データが入力アダプターを介して StreamInsight サーバーに挿入されると、そのデータに対して計算が連続的に実行されます。つまり、個々のイベントがサーバーに到着すると、これらのイベントは永続的なクエリによって処理されます。これにより、入力イベントの到着に応じて出力イベントが生成されます。実行時の StreamInsight クエリとアダプターを次の図に示します。入力アダプターのインスタンスがクエリのインスタンスにバインドされると、StreamInsight サーバーではイベントを使用して処理します。その後、処理されたデータは、同じクエリのインスタンスにバインドされている出力アダプターのインスタンスにプッシュされます。