@TOC
踩坑背景
流程如下所示:
1.使用SparkSQL獲取到了一個DataFrame暮芭;
2.然后map這個DataFrame热芹,調(diào)用GET接口,獲得了IDs作為一個新的DatdaFrame富玷;
3.最后再map這個DataFrame,在map中調(diào)用Post接口淀零,將最終結(jié)果放到接口中烛缔。
踩坑原因
因為比較懶,所以在spark-submit的時候砍鸠,腳本直接復(fù)制了另外一個Spark作業(yè)的提交腳本,但是萬萬沒想到的是:這個腳本里耕驰,有一句設(shè)置:--conf "spark.speculation=true"
爷辱,當(dāng)時沒注意,直接提交上去了朦肘。
后來反饋最終的Post接口存在重復(fù)調(diào)用的問題饭弓,有的name會調(diào)用兩次post接口,有的則只會調(diào)用一次媒抠。
解決
最后通過咨詢大佬得知示启,在嚴(yán)格執(zhí)行只能計算一次時,一定要把Spark的檢測執(zhí)行關(guān)掉领舰!也就是說,不要在代碼或者腳本里設(shè)置spark.speculation=true
迟螺,此配置Spark默認(rèn)為false冲秽。
原因
當(dāng)Spark開啟檢測執(zhí)行時,它會根據(jù)數(shù)據(jù)片的執(zhí)行時間來啟動第二次執(zhí)行矩父。即當(dāng)partition1里的數(shù)據(jù)在executor1上執(zhí)行超過一定時間锉桑,但是仍然沒有執(zhí)行完畢時,此時executor2會起一個程序開始運(yùn)行partition1里的數(shù)據(jù)窍株,哪個先運(yùn)行完民轴,就把剩下那個沒運(yùn)行完的kill掉攻柠,返回最終結(jié)果。
因為我的代碼中后裸,獲取Post連接的時間可能比較長瑰钮,超出了檢測執(zhí)行的時間范圍,于是部分超出檢測執(zhí)行范圍的name被啟動了executor2計算微驶,雖然在最終的返回狀態(tài)結(jié)果中只有一份數(shù)據(jù)浪谴,但是它實際上已經(jīng)調(diào)用了兩次,看到的返回狀態(tài)結(jié)果已經(jīng)不準(zhǔn)了因苹。
教訓(xùn)
別瞎cv苟耻,所有提交的東西都要搞清楚,細(xì)細(xì)思考過才可以扶檐。