問題
您正在運行Apache火花DataFrames執行連接操作的SQL查詢,但是查詢失敗的TimeoutException錯誤消息。
例子堆棧跟蹤
引起的:java . util . concurrent。TimeoutException: Futures timed out after [300 seconds]scala.concurrent.impl.Promise DefaultPromise.ready美元(Promise.scala: 219) scala.concurrent.impl.Promise DefaultPromise.result美元(Promise.scala: 223) 在scala.concurrent.Await anonfun結果美元1.美元申請(package.scala: 190) 在scala.concurrent.BlockContext DefaultBlockContext .blockOn美元(BlockContext.scala: 53)
導致
這個問題通常源於火花試圖執行廣播連接,當塊從不同的抓取執行人消耗過度的時間。
火花執行廣播加入使用bt協議。司機要播放的數據分解為小塊和數據塊存儲在塊的司機。司機也將大塊的數據發送到執行人。每個執行者保持副本的數據塊的塊經理。
當一個具體執行人不能獲取數據從本地塊的塊經理(執行人說死了,換)遺囑執行人試圖獲取廣播數據從司機以及其他執行者。這避免了司機在遠程請求服務的瓶頸。
即使這種分布式的方法,有些場景時間的廣播可以過量,導致TimeoutException錯誤。
- 繁忙的司機或忙碌的遺囑執行人:如果火花司機和執行人非常繁忙,它可以播放過程中引入延遲。如果廣播過程超過閾值時,就會導致一個廣播超時。
- 大廣播數據大小:試圖播放大量的數據也可以導致廣播超時。火花有一個默認的8 gb的限製廣播數據。
解決方案
您需要識別查詢導致資源在集群上的瓶頸。打開火花UI(AWS|Azure|GCP)和審查任何失敗的階段定位導致失敗的SQL查詢。審查引發SQL計劃是否使用BroadcastNestedLoopJoin。
- 如果火花SQL使用計劃BroadcastNestedLoopJoin,你需要遵循的指令禁用當查詢計劃BroadcastNestedLoopJoin播出篇文章。
- 如果火花不使用SQL的計劃BroadcastNestedLoopJoin,你可以禁用廣播加入通過設置火花配置值之前有問題的查詢。然後您可以恢複這些變化後,有問題的查詢。使改變查詢特定允許其他查詢,可以受益於廣播加入,還利用效益。
設置spark.sql.autoBroadcastJoinThreshold = 1
這種禁用廣播連接。設置spark.databricks.adaptive.autoBroadcastJoinThreshold = 1
這個配置禁用自適應廣播加入。
另一種選擇是增加spark.sql.broadcastTimeout值超過300秒,這是默認值。增加spark.sql.broadcastTimeout允許更多的時間廣播過程完成之前生成失敗。這種方法的缺點是,它可能導致查詢時間過長。
例如,設置值600雙打廣播加入的時間才能完成。
設置spark.sql.broadcastTimeout = 600
這個值可以設置集群級別或筆記本級別。