2016-12-25 56 views
2

我在本地模式下使用spark,並且一個簡單的連接花費的時間太長。我已經提取了兩個數據幀:A(8列和230萬行)和B(8列和120萬行),並使用A.join(B,condition,'left')加入它們,並最終調用動作。它創建了三個階段的單個作業,每個階段提取兩個數據幀,一個用於加入。令人驚訝的是,提取數據幀A的階段花費大約8分鐘,而數據幀B花費1分鐘。並且連接在幾秒鐘內發生。我的重要配置設置:爲什麼在本地模式下加入火花很慢?

  1. spark.master本地[*]
  2. spark.driver.cores 8
  3. spark.executor.memory30克
  4. spark.driver.memory30克
  5. 火花.serializer org.apache.spark.serializer.KryoSerializer
  6. spark.sql.shuffle.partitions 16

唯一的執行者是驅動程序本身。在提取數據幀的同時,我將它分區爲32(也試過16,64,50,100,200)部分。我已經看到,使用數據幀A提取將shuffle寫入內存爲100 MB。因此,爲了避免混洗,我爲數據幀和廣播數據幀B(較小)創建了16個初始分區,但這並沒有幫助。還有洗牌寫入記憶。我已經使用broadcast(B)語法。 我做錯了什麼?爲什麼洗牌仍然存在?另外,當我看到事件時間線,它顯示只有四個核心在任何時間點處理。雖然我有一個2core * 4處理器的機器。 這是爲什麼?

+0

輸入的大小是多少? – Yaron

+0

數據幀A包含280MB,對於B –

+0

也是140MB這些都是非常小的數據集...也許這樣? https://bzhangusc.wordpress.com/2015/06/10/why-your-join-is-so-slow/ – mathtick

回答

1

總之,「加入」 < =>洗牌,這裏最大的問題是如何被均勻分佈在分區數據(例如見https://0x0fff.com/spark-architecture-shuffle/https://www.slideshare.net/SparkSummit/handling-data-skew-adaptively-in-spark-using-dynamic-repartitioning和只是谷歌的問題)。 提高效率的幾種可能性:

  • 想想更多關於您的數據(A和B)和明智的分區數據;
  • 分析,你的數據是否傾斜?
  • 進入UI並查看任務計時;
  • 選擇這樣的密鑰用於「join」期間的分區只有少數幾個分區來自數據集A洗牌而只有少數B分區;