在Spark Streaming中,DStream的轉換分爲有狀態和無狀態兩種。無狀態的操作,即當前批次的處理不依賴於先前批次的數據,如map()、flatMap()、filter()、reduceByKey()、groupByKey()等等;而有狀態的操作,即當前批次的處理需要依賴先前批次的數據,這樣的話,就需要跨批次維護狀態。
總結spark streaming中的狀態操作:updateStateByKey、mapWithState
updateStateByKey
- 首先,要定義一個 state,可以是任意的數據類型;
- 其次,要定義 state 更新函數(指定一個函數如何使用之前的 state 和新值來更新 state)。 對於每個 batch,spark 都會爲每個之前已經存在的 key 去應用一次 state 更新函數,無論這個 key 在 batch 中是否有新的數據。如果 state 更新函數返回 none,那麼 key 對應的 state 就會被刪除。 當然對於每個新出現的 key 也會執行 state 更新函數。
mapWithState
mapWithState從spark 1.6.0開始出現,可以看做是updateStateByKey的升級版,有一些updateStateByKey所沒有的特徵:
1、支持輸出只發生更新的狀態和全量狀態
mapWithState默認每個批次只會返回當前批次中有新數據的Key的狀態,也可返回全量狀態。updateStateByKey每個批次都會返回所有狀態。
2、內置狀態超時管理
內置狀態超時管理,可對超時的Key單獨處理。也可實現如會話超時(Session Timeout)的功能。在updateStateByKey中,如果要實現類似功能,需要大量編碼。
3、初始化狀態
可以選擇自定義的RDD來初始化狀態。
4、可以返回任何我們期望的類型
由mapWithState函數可知,可以返回任何我們期望的類型,而updateStateByKey做不到這一點。
5、性能更高
實現上,mapWithState只是增量更新,updateStateByKey每個批次都會對歷史全量狀態和當前增量數據進行cogroup合併,狀態較大時,性能較低。