1.イベント時刻紹介
FLINKをストリーミングでは、企業の大半はイベント時刻が使用できない、またはProcessingTime IngestionTimeを使用するように強制されます、通常時にのみ、イベント時刻を使用します。
次のようにイベント時刻を使用するには、その後、イベント時刻の時間属性を導入する必要が導入方法です。
val env = StreamExecutionEnvironment.getExecutionEnvironment
// 从调用时刻开始给env创建的每一个stream追加时间特征
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
2.透かし
2.1基本概念
我々は、ソースを介して流れるように、処理が生成されたイベントストリームから、知っている、オペレータ、及び中間時間の過程で、ほとんどの場合、時系列、データフローは、イベントによって生成された演算子に応じてであるが、しかしネットワークはスクランブル、いわゆる障害をもたらす、背圧および他の理由を除外しないので、FLINKイベントを受信した配列を指すイベントのイベント時間配置の順序に従って厳密ではありません。
したがって、この時点でのみ決定ウィンドウのイベント時刻の実行に基づいて、我々は、データがすべての場所にあるかどうかを明確にすることができない場合は、一度、順不同で出現し問題があるが、無期限に待つことができない場合、特定のことを確保するためのメカニズムが存在しなければなりませんトリガ・ウィンドウを実行するのに必要な時間を算出した後、この特定の機構が透かしです。
透かしイベント時間は、データ自体は、対応するウォーターマークを運び、自ら隠し属性データである、進捗状況を測定するための仕組みです。
透かしは、イベントを処理するための外で、注文のうち正しい取り扱いイベントは、通常、ウォーターマークウィンドウ機構と連動して実施しました。
データを表示するための透かしデータ・ストリーム・タイムスタンプは、したがって、ウォーターマークウィンドウがトリガされることによって行われる、透かし未満達したれます。
透かしは遅延トリガー機構として理解することができる、我々は、時間Tの透かし遅延の長さを設定することができ、システムは、すべてのデータは、maxEventTimeよりイベント時刻以下を見つけ、最大maxEventTimeに達しているチェックする - がある場合、すべてのデータは、T到着されていますウィンドウ停止時間はmaxEventTimeに等しい - Tは、ウィンドウがトリガされます。
(透かしが0に設定):以下に示すように透かしは、ストリームを命じ
以下に示すように、透かしは、ストリームをスクランブル:(透かしが2に設定されています)
長時間の遅延、即ち、透かしによって運ばれるデータは現在の比によって運ばれるデータがトリガされていない後透かし - 各データFLINKを受信した場合、透かしを有するであろう、これは現在の透かしすべての着信データmaxEventTimeと同等です後で停止する時間の窓は、それが対応するウィンドウの実行をトリガします。透かしは、データによって行われるため、プロセスは、新たなデータを取得することはできません実行されている場合は、それゆえ、それは窓によってトリガされていないがトリガされることはありません。
上の図は、私たちは2秒のため、到着の最大遅延時間を設定することができますので、私たちのウィンドウが1つの1Sであれば透かし7S対応するイベントのタイムスタンプは、5Sは、12Sタイムスタンプ透かしイベントが10秒である5S、2窓6Sあるイベントがちょうど窓2をトリガー到着したときにイベントがトリガウィンドウ透かし1、タイムスタンプ透かし12Sのちょうどタイムスタンプを到着したときに10sが、その後、7S。
2.2透かしの導入
val env = StreamExecutionEnvironment.getExecutionEnvironment
// 从调用时刻开始给env创建的每一个stream追加时间特征
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
val stream = env.readTextFile("eventTest.txt").assignTimestampsAndWatermarks(
new BoundedOutOfOrdernessTimestampExtractor[String](Time.milliseconds(200)) {
override def extractTimestamp(t: String): Long = {
// EventTime是日志生成时间,我们从日志中解析EventTime
t.split(" ")(0).toLong
}
})
3. EventTimeWindow API
EventTimeWindowを使用する場合、すべてのウィンドウイベント時刻は、初期イベント時刻分割間隔に基づいて、ウィンドウ開始時刻ウィンドウ、ウィンドウサイズが3秒である場合、1分後、つまり、時間軸上で分割しますウィンドウには、以下のフォームに分割されます。
[00:00:00,00:00:03)
[00:00:03,00:00:06)
...
[00:00:57,00:01:00)
ウィンドウサイズが10秒である場合、ウィンドウは次の形式に分けることができます。
[00:00:00,00:00:10)
[00:00:10,00:00:20)
...
[00:00:50,00:01:00)
[window_start_time、window_end_time):ウィンドウが開いたままと形で、右が閉じていることに注意してください。
ウィンドウのデータは関係なく、自分自身の設定のが、システムの良い定義、すなわち、ウィンドウはデータがないこのウィンドウかどうか、分割することが指定された時間間隔に基づいてされているだろう、このWindow中のイベント時刻データは、このウィンドウに入ります。
ウィンドウを生産し続けるだろう、この範囲に属するウィンドウのデータは継続的に、すべてのトリガされない窓がない限り、トリガーウィンドウとして、この範囲に属するウィンドウのデータがウィンドウに追加されていたであろう、トリガを待ちます、ウィンドウに追加されますウィンドウは、追加データが停止するまで、トリガ、およびウィンドウ・トリガがトリガされたときにのみウィンドウのデータの一部が破棄されますました。
以下の条件が満たされたときにウィンドウが実行トリガされます。
- タイム透かし> = window_end_time。
- データはで[window_start_time、window_end_time)に存在します。
私たちは、次の図による関係ウォーターマーク、イベント時刻とウィンドウを示しています。
3.1ウィンドウ(TumblingEventTimeWindows)をスクロール
// 获取执行环境
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
// 创建SocketSource
val stream = env.socketTextStream("localhost", 11111)
// 对stream进行处理并按key聚合
val streamKeyBy = stream.assignTimestampsAndWatermarks(
new BoundedOutOfOrdernessTimestampExtractor[String](Time.milliseconds(3000)) {
override def extractTimestamp(element: String): Long = {
val sysTime = element.split(" ")(0).toLong
println(sysTime)
sysTime
}}).map(item => (item.split(" ")(1), 1)).keyBy(0)
// 引入滚动窗口
val streamWindow = streamKeyBy.window(TumblingEventTimeWindows.of(Time.seconds(10)))
// 执行聚合操作
val streamReduce = streamWindow.reduce(
(item1, item2) => (item1._1, item1._2 + item2._2)
)
// 将聚合数据写入文件
streamReduce.print
// 执行程序
env.execute("TumblingWindow")
結果にかかわらず(入力速度を含む)システムの時間の計算イベント時間に応じて時間窓です。
3.2スライディングウィンドウ(SlidingEventTimeWindows)
// 获取执行环境
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
// 创建SocketSource
val stream = env.socketTextStream("localhost", 11111)
// 对stream进行处理并按key聚合
val streamKeyBy = stream.assignTimestampsAndWatermarks(
new BoundedOutOfOrdernessTimestampExtractor[String](Time.milliseconds(0)) {
override def extractTimestamp(element: String): Long = {
val sysTime = element.split(" ")(0).toLong
println(sysTime)
sysTime
}}).map(item => (item.split(" ")(1), 1)).keyBy(0)
// 引入滚动窗口
val streamWindow = streamKeyBy.window(SlidingEventTimeWindows.of(Time.seconds(10), Time.seconds(5)))
// 执行聚合操作
val streamReduce = streamWindow.reduce(
(item1, item2) => (item1._1, item1._2 + item2._2)
)
// 将聚合数据写入文件
streamReduce.print
// 执行程序
env.execute("TumblingWindow")
3.3セッション・ウィンドウ(EventTimeSessionWindows)
指定された時間間隔で隣接する二つのデータ間のイベント時刻の時間差は、実行をトリガします。あなたは透かしを追加する場合は、トリガの実行は、ウィンドウには、すべての時間間隔がまだ同時にトリガ実行をトリガしていない会うとき。
// 获取执行环境
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
// 创建SocketSource
val stream = env.socketTextStream("localhost", 11111)
// 对stream进行处理并按key聚合
val streamKeyBy = stream.assignTimestampsAndWatermarks(
new BoundedOutOfOrdernessTimestampExtractor[String](Time.milliseconds(0)) {
override def extractTimestamp(element: String): Long = {
val sysTime = element.split(" ")(0).toLong
println(sysTime)
sysTime
}}).map(item => (item.split(" ")(1), 1)).keyBy(0)
// 引入滚动窗口
val streamWindow = streamKeyBy.window(EventTimeSessionWindows.withGap(Time.seconds(5)))
// 执行聚合操作
val streamReduce = streamWindow.reduce(
(item1, item2) => (item1._1, item1._2 + item2._2)
)
// 将聚合数据写入文件
streamReduce.print
// 执行程序
env.execute("TumblingWindow")