2016-06-16 88 views
4

如果我理解正確,當reduce任務開始收集其輸入洗牌塊(來自不同map任務的輸出)時,它首先將它們保留在內存(Q1)中。當執行程序的混洗保留內存量(在內存管理(Q2)更改之前)耗盡時,內存中的數據將「溢出」到磁盤。如果spark.shuffle.spill.compress爲true,那麼內存中的數據將以壓縮的方式寫入磁盤。瞭解Spark洗牌溢出

我的問題:

Q0:我的理解是否正確?

Q1:reduce任務中收集的數據是否始終未壓縮?

問題2:如何估算可用於收集混洗塊的執行器內存量?

Q3:我已經看到了「當數據集不適合內存時發生隨機溢出」這一說法,但只要洗牌保留的執行程序內存足夠大以包含所有(未壓縮)的洗牌輸入所有ACTIVE任務塊,那麼不會發生溢出,這是正確的嗎?

如果是這樣,爲了避免泄漏,需要確保所有並行reduce端任務中的(未壓縮)數據少於執行程序的shuffle-reserved內存部分?

+0

您使用1.6之前的精確版本的Spark嗎?你不能使用1.6.1的原因是什麼? – Sim

+0

我的大多數問題(除了與shuffle相關的內存的具體大小之外)都是一般的,對特定版本是不可知的。我在生產中使用1.3.1,因爲這是EMR AMI提供的。版本1.6.1可用於新版本的EMR(發佈標籤),我嘗試過但尚未生產。 –

+0

我強烈建議你切換到1.6.1。 1.3.1由Spark標準是古老的並且有很多問題;只需看看Spark的JIRA。性能提升可能會超過您通過手動調整1.3.1所能做的任何事情。 – Sim

回答

4

在1.6之前和之後的內存管理方面存在差異。在這兩種情況下,都有執行內存和存儲內存的概念。不同的是,在1.6之前它是靜態的。這意味着有一個配置參數,指定要執行和存儲多少內存。有一個泄漏,當任何一個都不夠時。

的問題之一阿帕奇火花必須解決方法是的併發執行:即在像聚集或排序平行

  • 不同的任務執行

    • 不同階段。

    1. 我會說,你的理解是正確的。

    2. 內存中的內容是未壓縮的,否則無法處理。執行內存以塊的形式泄漏到磁盤,正如你所提到的那樣可以被壓縮。

    3. 那麼,從1.3.1開始,你可以配置它,然後你就知道它的大小。至於什麼時候留下什麼,你可以通過查看執行器進程來看到類似jstat -gcutil <pid> <period>的東西。它可能會給你一個有多少內存空閒的線索。知道爲存儲和執行配置了多少內存,儘可能少的內存可能會給你一個線索。

    4. 確實如此,但很難推理;數據可能存在偏差,例如某些按鍵比其他按鍵具有更多的值,並行執行很多等。