流式重複數據刪除
我們可以使用事件中的唯一標識符對數據流中的記錄進行重複數據刪除。這與使用唯一標識列的靜態重複數據刪除完全相同。該查詢將存儲來自先前記錄的必要數據量,以便它可以過濾重複記錄。與聚合類似,我們可以使用帶或不帶水印的重複數據刪除。
- 使用水印:如果重複記錄的到達時間有上線,則可以再事件時間列上定義水印,並使用guid和事件時間列進行重複數據刪除。該查詢將使用水印從過去的記錄中刪除舊的狀態數據,這些記錄不會再被重複。這限制了查詢必須維護的狀態量。
- 沒有水印:由於重複記錄可能到達時沒有界限,查詢將來自所有過去記錄的數據存儲爲狀態。
Dataset<Row> streamingDf = spark.readStream(). ...; // columns: guid, eventTime, ...
// Without watermark using guid column
streamingDf.dropDuplicates("guid");
// With watermark using guid and eventTime columns
streamingDf
.withWatermark("eventTime", "10 seconds")
.dropDuplicates("guid", "eventTime");
任意有狀態的操作
許多用例需要比聚合更高級的有狀態操作。例如,在許多用例中,我們必須從事件的數據流中跟蹤會話。要進行此類會話,我們必須將任意類型的數據保存爲狀態,並使用每個觸發器中的數據流事件對狀態執行任意操作。從Spark2.2開始,這可以通過操作mapGroupWithState和更強大的操作來完成flatMapGroupWithState。這兩個操作都允許我們在分組數據集上應用用戶定義的代碼以更新用戶定義的狀態。
不支持的操作
流式DataFrames/Datasets不支持一些DataFrame/Dataset操作。其中一些如下:
- 流數據集尚不支持多個流聚合(即流式DF上的聚合鏈)。
- 流數據集不支持限制和獲取前N行。
- 流數據集不支持去重操作。
- 僅在聚合、完全輸出模式之後,流數據集才支持排序操作。
- 不支持流數據集上的幾種外連接類型。
此外,有一些數據集方法不適用於流數據集。它們時立即運行查詢並返回結果的操作,這對流式數據集沒有意義。相反,這些功能可以通過顯示啓動流式查詢來完成。
- count():無法從流式數據集返回單個計數。而是使用ds.groupBy().count()返回包含運行計數的流數據集。
- foreach():流數據集使用ds.writeStream.foreach()
- show():使用控制檯接收器。
如果我們嘗試任何這些操作,我們將看到AnalysisException類似“Stream DataFrame/Dataset不支持操作***”。雖然其中一些可能在未來的Spark版本中得到支持,但還有一些基本上難以有效地實現流數據。例如,不支持對輸入流進行排序,因爲它需要跟蹤流中接收的所有數據。因此,這基本上難以有效執行。