Flink-EventTime數據測試 | watermark、allowedLateness、sideOutputLateData 三重保證數據不丟失

程序代碼

import com.atguigu.bean.SensorReading
import com.atguigu.window.MyReduceFunc
import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.windowing.time.Time


object EventTimeTest {
  def main(args: Array[String]): Unit = {

    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment

    env.setParallelism(1)
    // 從調用時刻開始給env創建的每一個stream追加時間特徵
    env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
    // 設置watermark的默認生成周期 -> 100毫秒生成一個WaterMark
    env.getConfig.setAutoWatermarkInterval(100L)

    val inputDStream: DataStream[String] = env.socketTextStream("hadoop102", 7777)

    val dataDstream: DataStream[SensorReading] = inputDStream
      .map( data => {
        val dataArray: Array[String] = data.split(",")
        SensorReading(dataArray(0), dataArray(1).toLong, dataArray(2).toDouble)
      })
      // .assignAscendingTimestamps( _.timestamp * 1000L ) // 理想狀態下直接指定時間戳字段就可以了
      .assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor[SensorReading]
        // 給WaterMark的一個初始值延時時間
        (Time.milliseconds(1000)) {
        // 指定時間戳字段以秒爲單位 * 1000
          override def extractTimestamp(element: SensorReading): Long = element.timestamp * 1000L
      })

    // 三重保證 watermark(水位線) | allowedLateness(最大遲到數據)  | sideOutputLateData(側輸出流)
    val resultDStream: DataStream[SensorReading] = dataDstream
        .keyBy("id")
        .timeWindow( Time.seconds(5) )
        .allowedLateness( Time.minutes(1) )
        .sideOutputLateData( new OutputTag[SensorReading]("late") )
        .reduce( MyReduceFunc() )

    dataDstream.print("data")
    resultDStream.print("result")
    // 獲取測輸出流的late並打印
    resultDStream.getSideOutput( new OutputTag[SensorReading]("late") ).print("late")

    env.execute("eventTime test job")

  }
}

在這裏插入圖片描述

水平線watermark

窗口關閉爲5秒,watermark延時爲1秒,所以其實窗口數據只要[0,5), 5取不到(其實具體的時間戳的窗口從哪開始到那結束會有一個方法,並不是第一條數據時間戳是0就往後延長5秒,下面會看到),但是因爲watermark延長了1s 輸出到了時間戳6秒的時候纔會進行輸出,這時候窗口並沒有關閉,因爲我們設置了遲到數據allowedLateness

在這裏插入圖片描述

遲到數據allowedLateness

遲到數據設置成了一分鐘,這一分鐘之類所有的在[0,5)時間戳裏的數據都會進行輸出,來一條輸出。一分鐘後窗口才是正式關閉

在這裏插入圖片描述

側輸出流sideOutputLateData

兜底保證,窗口在關閉後,把數據輸出到側輸出流,之後看到late的數據可以進行和之前的數據進行手動合併
在這裏插入圖片描述

實際窗口時間戳程序底層算法

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章