2015-06-27 68 views
0

我正在Spark羣集上分發一些下載任務。輸入來自一個源,它不能總是與Spark的常規方法並行,如parallelizetextFile等等。相反,我有一個服務爲我提供了一堆使用parallelize分發的下載任務(URL +封裝的邏輯來讀取和解密它)。控制Spark中任務的分配

當有幾千個任務時,Spark將任務平均分配給所有從服務器,從而實現最高水平的並行性。但是,當有幾百個任務時,Spark認爲數據集很小,可以在幾個從站上計算,以減少通信時間並增加數據局部性。但是在我的情況中,這是錯誤的,每個任務都可以生成數千個JSON記錄,並且我希望下載能夠通過與羣集中一樣多的機器來執行。

我的那一刻兩個想法:

  • 使用repartition到分區的數量設置爲使用repartition設置分區的號碼下載任務數的核心
  • 數量

我不喜歡第一個,因爲我必須傳遞一段代碼中的核心數量,這些代碼當前並不需要知道它有多少資源。我一次只運行一個Spark作業,但將來可能會有更多這樣的作業,所以實際上我必須將核心數量除以要在羣集上運行的並行作業數量。我不喜歡第二個,因爲當我只有40個節點時,劃分成數千個分區似乎很尷尬。

有沒有辦法告訴Spark儘可能分配RDD的元素?如果不是,兩種選擇中的哪一種更可取?

+0

你說你不能使用'parallelize'並且你也使用'parallelize'。我理解正確嗎? :) –

+0

啊,我想我明白了!你的意思是你沒有預先提供的數據,只有網址。所以你不能通過'parallelize'分發數據,而是使用'parallelize'來分發這些URL。不介意我... –

+0

@DanielDarabos你說得對了 – Dici

回答

1

如果每次下載都能產生大量記錄,而且下載量也不會很多(只有幾千個),我建議在每次下載時創建一個分區

調度幾千個任務的總開銷只有幾秒鐘。我們通常在生產中擁有數萬個分區。

如果您在一個分區中有多次下載,最終可能會出現非常大的分區。如果你有一個分區無法整合兩次可用內存,那麼你將會遇到一些操作問題。例如,一個joindistinct構建整個分區的散列表。


您不應該使用repartitionparallelize需要第二個參數,即需要的分區數量。儘管URL列表並不是大量數據,但如果您只是使用適當數量的分區創建RDD,而不是在創建之後對其進行重新組合,那將會更好。

+0

嗨,你的回答很有道理,因此我贊成它。我現在不接受,因爲我想在星期一之前測試它。我還有一個問題:當你的羣集中有更多的分區而不是節點(和核心)時,幾個分區是由相同的節點計算出來的嗎?那麼,如何將節點分成儘可能多的節點,又有哪些不同? – Dici

+0

每個分區都成爲一個計算單位(Spark _任務_)。無論您有多少個小型工作單元,或者更少的大型單元,無論內核的數量如何,都會有所不同。調度任務有一些開銷。如果您有N個分區,洗牌會創建N^2個塊。分區有時必須適合內存。等等無論如何,最好是在你決定之前測試兩個選項,如果你能做一個有代表性的測試! –

+0

好的,謝謝你的回答,我會在星期一嘗試,讓你知道! – Dici