背景
使用PySpark抽取數據同步到數據庫時候(例如:clickhouse、mysql等數據庫),使用RDD的foreachPartition
、mapPartitions
或mapPartitionsWithIndex
等函數發現有的數據會執行同步多次,導致重複數據問題。
原因及解決方案
可以通過mapPartitionsWithIndex
的函數打印partitionIndex
,然後在日誌查看的方式定位原因,綜合分析可能由於以下三個原因導致:
-
1、代碼中設置了spark推測執行開啓
spark.speculation=true
(默認是false)導致,該參數的作用是:同時啓動多個相同task(備份任務)處理相同的數據塊,哪個完成的早,則採用哪個task的結果,同時終止其他的task。對於同步數據的場景該參數應該設置爲spark.speculation=false
-
2、由於Spark的RDD的父依賴重算機制,下游子RDD運行中有可能導致上游未緩存的RDD重新計算,此時建議該同步數據算子執行後
persist
一下 -
3、executor的失敗重試可能導致,由於是偶然性事件,因此建議同步完,
增加需同步數據量和實際同步數據量相等校驗
。