Flink DataStream API 介紹

DataStream 編程模型

  • DataSource模塊負責數據接入
    • 內置數據源:文件數據源readTextFile/readFile(InputFormat),Socket端口socketTextStream,集合數據源 fromElements
    • 第三方數據源:
      • 僅支持讀取:Netty
      • 僅支持輸出:ElasticSearch,HDFS
      • 支持讀取和輸出:Kafaka,RabbitMQ
      • 用戶自定義數據源連接器
  • Transformation模塊負責數據集的各種轉換操作
    • 單SingleDataStream:對單個DataStream的處理邏輯
      • Map[DataStream->DataStream],map函數可以直接傳入匿名計算表達式,也可以實現匿名的MapFunction類,覆蓋其中的map方法。
      • FlatMap[DataStream->DataStream]
      • Filter[DataStream->DataStream],符合表達式的留下來,不符合的過濾掉。
      • KeyBy[DataStream->KeyedStream],執行Partition操作,將相同的Key值放入相同的分區。
      • Reduce[KeyedStream->DataStream],可直接傳入匿名的reduce函數,也可實現匿名的ReduceFunction類。
      • Aggregations[KeyedStream->DataStream], 根據指定的字段進行聚合操作,滾動計算參數聚合結果,即一個reduce操作個例。例如 sum,min,minBy(返回最小值對應的元素),max,maxBy
    • MultiDataStream:對多個DataStream的處理邏輯
      • Union[DataStream->DataStream],需要保證兩個數據集的格式一致。
      • Connect,CoMap,CoFlatMap[DataStream->DataStream]
      • Split[DataStream->SplitStream]
      • Select[SplitStream->DataStream]
      • Iterate[DataStream->IterativeStream->DataStream]
    • 物理分區:並行度和數據分區的調整轉換
      • shuffle:隨機重新分區,分區相對平衡,但是容易失去原有的數據分區結構。
      • rebalance:通過循環的方式對數據集中的數據進行重分區,儘可能地保證每個分區的數據平衡。
      • rescale:循環處理,並僅會對上下游的算子數據進行重新平衡。
      • broadcast:將數據集複製到下游的算子task中,防止網絡拉取。
      • 自定義分區 extends Partitioner
  • DataSink模塊負責寫出到外部存儲
    • 基本數據輸出:writeAsCsv,writeAsText,writeToSocket
    • 第三方數據輸出:FlinkKafkaProducer

時間概念與Watermark

時間的概念

  • 事件生成時間 Event Time,時間實際發生時間

  • 事件接入時間 Ingestion Time,傳送至DataSource時的機器時間

  • 事件處理時間 Processing Time,到達某個算子操作時獲取的機器時間
    在Flink中默認情況下使用的是Process Time,因此要使用其他兩種時間時,需要顯示指定。

 //指定時間類型
 env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)

EventTime和Watermark

Watermark是水位線的意思,一個基於事件時間的Window是水槽,Watermark用於判斷該水槽中的水是否全部流入了,是一個表達數據完整性的統計量。

Watermark=EventTime-最大延遲到達時間

當窗口結束時間大於Watermark,並且該窗口中有事件數據時,就會觸發窗口計算。

Timestamps Assigning與生成Watermarks

使用EventTime需要說明如何從事件數據中提取Timestamp,該過程叫做Timestams Assigning。

得到EventTime之後,需要制定Watermarks的生成策略。

兩種方式:

  • 在DataStream Source 算子接口的Source Function 中定義。

  • 通過Flink自帶的Timestamp Assigner 指定Timestamp 和生成Watermark

    • 根據時間間隔週期性生成Watermark,AssignerWithPeriodicWatermarks

      • 升序模式,適用於順序生成事件:assignAscendingTimestamps

      • 固定時間延遲間隔

        assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor[AdsStateRealEntity](Time.minutes(1)) // 指定時間間隔爲1分鐘
                                {
           // 指定事件時間抽取方式
          override def extractTimestamp(element: AdsStateRealEntity): Long = getUnixTime(element.getStatusStartTime)  })
    
    • 根據特定元素的數據滿足某個特定條件生成Watermark,AssignerWithPunctuatedWatermarks
  • 自定義Timestamp Assinger 和 WartermarkGenerator。

    • Periodic Watermarks 自定義生成

    • Punctuated Watermarks 自定義生成

窗口計算

WindowsAssigner :指定窗口的類型,定義如何將數據流分配到一個或者多個窗口。

Windows Trigger:指定窗口觸發時機,定義窗口滿足什麼樣的條件觸發計算。

Evictor:用於數據剔除。

Lateness:標記是否處理遲到數據,當遲到數據到達窗口中是否觸發計算。

OutPut Tag:標記輸出標籤,然後通過getSideOutput將窗口中的數據根據標籤輸出。

Windows Function:定義窗口上數據處理的邏輯,例如對數據進行sum操作。

stream.keyBy( ... ) // window函數窗口操作必須是keyedStream,否則應該調用windowAll方法
.window( ... ) // 指定窗口分配器類型
[.trigger( ... )]// 指定觸發器類型(可選)
[.evictor( ... )]// 指定evictor(可選)
[.allowedLateness( ... )] // 指定是否延遲處理數據(可選)
[.sideOutputLateData( ... )] // 指定Output Tag (可選)
.reduce/aggregate/fold/apply() // 指定窗口計算函數
[.getSideOutput( ... )] // 根據Tag輸出數據(可選)

Windows Assigner

基於時間的窗口

​ TimeWindow 類來獲取窗口的起始時間和終止時間,以及該窗口允許進入的最新時間戳信息等元數據。

​ (1)滾動窗口:根據固定時間或者大小進行切分,且窗口和窗口之間的元素互不重疊。

​ TumblingEventTimeWindows 和 TumblingProcessTimeWindows 或者 timeWindow方法。

​ (2)滑動窗口:在滾動窗口的基礎之上,增加了窗口的滑動時間,並且允許數據重疊。窗口的大小,和滑動時間兩個參數確定了滑動的策略。當Slide time 小於 Windows size 是便會發生重疊。而當Slide time 大於 Windows 四則時則會發生不連續。

​ (3)會話窗口:會話窗口(Session Windows)主要是將某段時間內活躍度較高的數據聚合成一個窗口進行計算,窗口的觸發條件是Session Gap,是指在規定的時間內如果沒有數據活躍接入,則認爲窗口結束,然後觸發窗口計算。可以通過實現SessionWindowTimeGapExtractor接口,複寫extract方法動態定義session gap。

​ (4)全局窗口:全局窗口將所有相同的Key的數據分配到單個窗口中計算結果,窗口沒有起始時間和結束時間,窗口需要藉助Trigger來觸發計算,如果不對Global Windows 指定Trigger,窗口是不會觸發計算的

基於數量的窗口

​ countWindows()來定義基於數量的窗口。

Windows Function

  • 增量聚合函數
    • ReduceFunction
    • AggregateFunction
    • FoldFunction
  • 全量窗口函數
    • ProcessWindowFunction

Trigger 窗口觸發器

​ EventTimeTrigger:通過對比Wartermark 和窗口的EndTime 確定是否觸發窗口,如果Wartermark的時間大於Windows EndTime 則觸發計算,否則窗口繼續等待。

​ ProcessTimeTrigger:和EventTimeTrigger類似,只是使用ProcessTime確定。

​ ContinuousEventTimeTrigger:根據時間間隔週期性觸發窗口或者Window的結束時間小於當前EventTime觸發窗口計算。

​ ContinuousProcessingTimeTrigger:同上

​ CountTrigger:根據接入數據量是否超過設定的閾值確定是否觸發窗口計算。

​ DeltaTrigger:根據接入數據計算出來的Delta指標是否超過指定的Threshold來判斷是否觸發窗口計算。

​ PurgingTrigger:可將將任意觸發器作爲參數轉換爲Purge類型觸發器,計算完成後數據將被清理。

​ 另外,用戶可以自定義Trigger。

Evictors 數據剔除器

​ 數據剔除器的主要作用是對進入WindowFunction前後的數據進行剔除處理。

  • CountEvictor:保持在窗口中具有固定數量的記錄,將超過指定大小的數據在窗口計算前剔除。
  • DeltaEvictor:通過定義DeltaFunction 和 指定 threshold,並計算Windows中元素與最新元素之間的Delta大小,如果超過threshold則將當前數據元素剔除。
  • TimeEvictor:通過指定時間間隔,將當前窗口中最新元素的時間減去Interval,然後將小於該結果的數據全部剔除,其本質是將具有最新時間的數據選擇出來,刪除過時數據。
  • 用戶可自定義Evictor

延遲數據處理

​ 基於Event-Time的窗口處理流式數據,在延遲非常高的情況下,依然會有部分數據未來得及進入應該進的窗口,Flink默認情況下是將這些數據丟棄,而Allowed Lateness機制對遲到的數據進行額外的處理。

​ 對於指定了allowedLateness的窗口,計算過程中的Window的Endtime會加上該時間,作爲窗口最後被釋放的結束時間(P),如果EventTime超過了P則丟棄數據,如果EventTime未超過P,但是Wartermark已經超過Endtime則觸發計算,對於未參與計算的數據,可以通過sideOutputLateData方法打上late-data標籤,然後通過getSideOutput方法獲取該標籤的數據,進行額外處理。

窗口計算

獨立窗口計算:針對同一個DataStream進行不同的窗口處理,窗口之間相對獨立,輸出結果在不同的DataStream中,這時在Flink Runtime 執行環境中,將分爲兩個Window Operator 在不同的Task中執行,相互之間的元數據無法共享。

連續窗口計算:連續窗口計算表示上游窗口計算的結果是下游窗口計算的輸入,窗口算子和算子之間是上下游關聯關係,窗口之間的元數據信息能夠共享。例如求每個key的最小值中最大的n個key。

Windows 多流合併 Join操作

​ 在Windows Join 過程中所有的Join操作都是Inner-join類型,兩個關聯的窗口必須是同類型的。

​ 滾動窗口關聯(Tumbling Window join)

​ 滑動窗口關聯(Sliding Window join)

​ 會話窗口關聯(Session Window join)

​ 間隔窗口關聯(Interval Join)

作業鏈和資源組

​ 在Flink作業中,用戶可以指定相應的鏈條,將相關性非常強的轉換操作綁定在一起,這樣能夠讓轉換過程上下游的Task在同一個Pipeline中執行。

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