Flink Windows 多流 Join 和 SQL Join

Flink Windows Join 都是 Inner Join

兩個流join時,先做join操作,形成JoinedStream,然後再指定Window,最後接着join後的transform操作。

案例:

inputStream1:DataStream[(Long,String,Int)] = ...
inputStream2:DataStream[(String,Long,Int)] = ...
//通過DataStream Join方法將兩個數據流關聯
inputStream1.join(inputStream2)
    //指定inputStream1的關聯Key
    .where(_._1) 
    //指定inputStream2的關聯Key
    .equalTo(_._2)/
    //指定Window Assigner
    .window(TumblingEventTimeWindows.of(Time.milliseconds(10)))
  .apply(<JoinFunction>) //指定窗口計算函數

根據窗口的不同,數據計算的方式不同

根據窗口的選擇,依次對應於:

滾動窗口關聯:Tumbling Window Join

滑動窗口關聯:Sliding Window Join

會話窗口關聯:Session Window Join

間隔關聯:Interval Join

間隔關聯 Join

間隔關聯與其他窗口關聯不同,間隔關聯的數據元素關聯範圍不依賴窗口劃分,而是通過DataStream元素的時間加上或減去指定Interval作爲關聯窗口,然後和另外一個DataStream的數據元素時間在窗口內進行Join操作。

示例代碼:


//創建黑色元素數據集
val blackStream: DataStream[(Int, Long)] = env.fromElements((2, 21L), (4, 1L), (5, 4L))
//創建白色元素數據集
val whiteStream: DataStream[(Int, Long)] = env.fromElements((2, 21L), (1, 1L), (3, 4L))
//通過Join方法將兩個數據集進行關聯
val windowStream: DataStream[String] = blackStream.keyBy(_._1)
//調用intervalJoin方法關聯另外一個DataStream
  .intervalJoin(whiteStream.keyBy(_._1))
//設定時間上限和下限
  .between(Time.milliseconds(-2), Time.milliseconds(1))
  .process(new ProcessWindowFunciton())
//通過單獨定義ProcessWindowFunciton實現ProcessJoinFunction
class ProcessWindowFunciton extends ProcessJoinFunction[(Int, Long), (Int, Long), String] {
  override def processElement(in1: (Int, Long), in2: (Int, Long), context: ProcessJoinFunction[(Int, Long), (Int, Long), String]#Context, collector: Collector[String]): Unit = {
    collector.collect(in1  + ":" + (in1._2 + in2._2))
  }
}

Flink SQL Join

經典的Join算法-歸併連接算法

經典的Join算法-哈希連接算法

Flink 流式SQL - 普通連接Join

對於不帶窗口的全量連接,內部Join算子,會維護A、B兩張表的哈希索引。當A表中插入一條數據時會查B的索引,尋找Join的條件數據,同時將本條數據加入A的索引。反之亦然。但是這種join會隨着數據量的增加,哈希表維護成本可能會無限增長下去。

解決方式是通過狀態TTL等手段加以限制。

Flink 流式SQL - 基於時間窗口連接Join

Flink 流式SQL - 基於待時間記錄的歷史表連接

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