2016-06-23 93 views
1

我正在使用hadoop集羣運行Spark程序,該程序使用紗線調度程序來運行任務。但是,我注意到一個奇怪的行爲。紗線有時會殺死一個抱怨內存錯誤的任務,而如果我在輪次中執行任務,即執行與容器/執行程序相同數量的任務,讓它們完成,然後執行下一組任務,它會正常運行意味着任務沒有使用比容器中允許的更多的內存。所以,我懷疑紗線試圖在一個容器中同時運行多個任務,這就是爲什麼容器內存不足的原因。有沒有辦法限制這種行爲,並告訴紗線一次只能在一個容器中運行一個任務。限制紗線容器一次只能執行一項任務

+0

您可以添加更多有關您遵循的兩種方法的詳細信息,例如多少個執行程序和執行程序內存。你如何運行不同的任務組(基於內存?)。同樣是在集羣上運行的任何其他應用程序使用YARN – Ramzy

+0

基本上在第一種方法中,我只是使用map。在第二種方法中,我每次運行程序多次,任務數量等於執行程序的數量。當我這樣做時,它可以正常工作,但是當我簡單地使用map並一次運行它時,它就會失敗。 – pythonic

回答

2

通常,Spark請求的每個YARN容器都直接對應一個「執行器」,即使YARN可能報告每個容器分配的1個CPU,Spark也會使用spark.executor.cores設置來確定打包到單個執行器中的併發任務數/容器進程。

因此,只需設置spark.executor.cores=1,每個YARN容器一次只能處理一個任務。這可以做爲​​配置,如--conf spark.executor.cores=1或者你可以把它放在conf/spark-defaults.conf(在大多數標準的hadoop安裝中,這將在/etc/spark/conf/spark-defaults.conf之內)。

請注意,每臺機器仍可能有多個YARN容器;如果要每機器一次進一步限制1個任務,則還需要將spark.executor.memory擴展爲每臺機器上可用的內存量(分配給在該機器上運行的YARN NodeManagers; YARN將拒絕打包所有容器大於你告訴NodeManager它允許使用,即使物理內存較大)。或者你可能會發現你簡單地需要將你的機器分割成更大的塊,所以你可以使用這個內存設置來找到合適的內存大小,而不會犧牲太多的並行性。

+0

HI @Dennis Huo,爲什麼不把執行程序設置爲1.內核只是處理並行性的執行程序的頂層。 – Ramzy

+0

你的意思是設置'spark.executor.instances = 1'?在這個問題中,YARN指出,爲了超過內存限制,YARN會殺死容器,這表明問題在於每個容器內Spark執行環境的*形成,而不是Spark應用程序如何包裝到YARN本身。例如,如果spark.executor.cores目前默認配置爲16,請求'spark.executor.instances = 1'只會限制應用程序在單個YARN容器中運行,但它仍然會嘗試執行16次在任何內存中配置並行的東西 –

+0

在這種情況下,大概pythonic仍然想要利用任何可用的並行機制,並且只需確保每個容器的形狀能夠正確地適應任務。所以說每臺機器有16個核心和16 GB的RAM,但每個任務都需要將4GB加載到內存中。如果spark.executor.instances = 1,spark.executor.cores = 16,spark.executor.memory = 16G,則Spark將抓取1個容器並嘗試一次運行16個任務。然後它將被YARN踢出去,因爲這16個任務將嘗試在該容器中使用總共16 * 4GB == 64GB。 –