GitHub
https://github.com/SmallScorpion/flink-tutorial.git
將錶轉換成DataStream
- 表可以轉換爲 DataStream 或 DataSet ,這樣自定義流處理或批處理程序就可以繼續在 Table API 或 SQL 查詢的結果上運行了
- 將錶轉換爲 DataStream 或 DataSet 時,需要指定生成的數據類型,即要將表的每一行轉換成的數據類型
- 表作爲流式查詢的結果,是動態更新的
- 轉換有兩種轉換模式:追加(Appende)模式和撤回(Retract)模式
- 追加模式:用於表只會被插入(Insert)操作更改的場景。
- 撤回模式:用於任何場景。有些類似於更新模式中Retract模式,它只有Insert和Delete兩類操作。(得到的數據會增加一個Boolean類型的標識位(返回的第一個字段),用它來表示到底是新增的數據(Insert),還是被刪除的數據(老數據, Delete)。)
// 追加模式
val resultStream: DataStream[Row] = tableEnv.toAppendStream[Row](resultTable)
// 撤回模式
val aggResultStream: DataStream[(Boolean, (String, Long))] = tableEnv
.toRetractStream[(String, Long)](aggResultTable)
沒有經過groupby之類聚合操作,可以直接用 toAppendStream 來轉換;而如果經過了聚合,有更新操作,一般就必須用 toRetractDstream。
查看執行計劃
Blink版本是批流統一的,所以所有的Query,只會被解釋成DataStream程序;另外在批處理環境TableEnvironment下,Blink版本要到tableEnv.execute()執行調用纔開始解釋。
// 查看執行計劃
val explaination: String = tableEnv.explain( resultTable )
// 測試
println(explaination)
流處理和關係代數的區別
Table API和SQL,本質上還是基於關係型表的操作方式;而關係型表、關係代數,以及SQL本身,一般是有界的,更適合批處理的場景。這就導致在進行流處理的過程中,理解會稍微複雜一些,需要引入一些特殊概念。
可以看到,其實關係代數(主要就是指關係型數據庫中的表)和SQL,主要就是針對批處理的,這和流處理有天生的隔閡。
動態表(Dynamic Tables)
- 因爲流處理面對的數據,是連續不斷的,這和我們熟悉的關係型數據庫中保存的“表”完全不同。所以,如果我們把流數據轉換成Table,然後執行類似於table的select操作,結果就不是一成不變的,而是隨着新數據的到來,會不停更新。
- 我們可以隨着新數據的到來,不停地在之前的基礎上更新結果。這樣得到的表,在Flink Table API概念裏,就叫做“動態表”(Dynamic Tables)。
- 動態表是 Flink 對流數據的 Table API 和 SQL 支持的核心概念
- 與表示批處理數據的靜態表不同,動態表是隨時間變化的
- 動態表可以像靜態的批處理表一樣進行查詢,查詢一個動態表會產生持續查詢(Continuous Query)。
- 連續查詢永遠不會終止,並會生成另一個動態表
- 查詢(Query)會不斷更新其動態結果表,以反映其動態輸入表上的更改。
流式持續查詢的過程
- 流被轉換爲動態表。
- 對動態表計算連續查詢,生成新的動態表。
- 生成的動態表被轉換回流。
將流轉換成動態表
- 爲了處理帶有關係查詢的流,必須先將其轉換爲表
- 從概念上講,流的每個數據記錄,都被解釋爲對結果表的插入(Insert)修改操作
- 本質上,我們其實是從一個、只有插入操作的changelog(更新日誌)流,來構建一個表。
- 來一條數據插入一條數據
持續查詢(Continuous Query)
- 持續查詢,會在動態表上做計算處理,並作爲結果生成新的動態表。與批處理查詢不同,連續查詢從不終止,並根據輸入表上的更新更新其結果表。
- 在任何時間點,連續查詢的結果在語義上,等同於在輸入表的快照上,以批處理模式執行的同一查詢的結果。
- 下圖爲一個點擊事件流的持續查詢,是一個分組聚合做count統計的查詢。
它將用戶字段上的clicks表分組,並統計訪問的url數。圖中顯示了隨着時間的推移,當clicks表被其他行更新時如何計算查詢。
將動態錶轉換成 DataStream
- 與常規的數據庫表一樣,動態表可以通過插入(Insert)、更新(Update)和刪除(Delete)更改,進行持續的修改
- 將動態錶轉換爲流或將其寫入外部系統時,需要對這些更改進行編碼
- 追加流: 就是這個流中發出的數據,就是動態表中新增的每一行。
- 撤回流: 動態表通過將INSERT 編碼爲add消息、DELETE 編碼爲retract消息、UPDATE編碼爲被更改行(前一行)的retract消息和更新後行(新行)的add消息,轉換爲retract流。
- 更新流: 通過將INSERT和UPDATE更改編碼爲upsert消息,將DELETE更改編碼爲DELETE消息,就可以將具有唯一鍵(Unique Key)的動態錶轉換爲流。