我想我有一個初學者的bug,但我真的不知道如何解決它,這讓我瘋狂。 我具有由2臺機器的羣集:Spark/Hadoop作業沒有運行在parralel
- 8GB RAM(6.9可用),4個芯,Win10:運行一個主,一個工人,而且它也從我正在運行的Java驅動程序程序(本機來自的IntelliJ)
- 2GB RAM(1.3可用),4芯的,Ubuntu 16.04的VM(拼命地跑在了VBox):運行一個工人
我有一個類網絡,我想生成一個for循環網絡從單一網絡的列表開始,然後通過使用平面映射將每個網絡變換成N個新網絡。之後,我有一個過濾器和一個計數。步驟:
JavaSparkContext sc = new JavaSparkContext(conf);
List<Network> data = Arrays.asList(new Network());
JavaRDD<Network> currentN = sc.parallelize(data);
for(int k=1;k<=10;k++) {
JavaRDD<Network> newN = currentN.flatMap(new MyFlatMap());
currentN = newN;
}
JavaRDD<Network> filteredNetworks = currentN.filter(new MyFilter());
System.out.println(filteredNetworks.count());
算法工作並輸出正確的值。
然而,通過比較在不同的應用場景的持續時間,我傾向於認爲本申請並不平行拼命地跑:使用兩臺機器,總公羊和8核的2GB的
羣集:持續時間1,5分鐘,只使用第二機(VM Ubuntu的),1GB RAM
羣集,4芯:持續時間1,1分鐘
羣集僅使用所述第一機器(其是一名高手,一名工人,和司機),1GB內存,4芯:持續3,2分鐘
截圖我的火花UI的:
我不知道爲什麼在運行Ubuntu的一個虛擬機的機器比主機快(這是主,工人和驅動程序),因爲該主機具有更好的CPU (i7 2.6GHZ與i3 1,9GHZ相比)。
但是主要問題是爲什麼在單臺機器上運行比在兩臺機器上運行都快?難道不是相反嗎?我的猜測是RDD不是並行計算的。如果是這種情況,請你解釋爲什麼以及如何使它能夠並行處理?
解釋的工作做什麼:
基本上,這就是我想要的,以實現循環的:
我從1開始網絡的RDD(它不是一個文件,它的只是一個小班)。
在for循環中,我使用flatMap將1個網絡轉換爲10個新網絡。
Iteration0:currentN = 1網絡 - > flatMap - > currentN = 10個網絡
Iteration1:currentN = 10網絡 - > flatMap - > currentN = 100個網絡
。 。
Iteration9:currentN = 10^8個網絡 - > flatMap - > currentN = 10^9網絡
因此,正如我說,我生成輸入。我想這樣做並行生成,所以這意味着flatMap需要並行執行。爲了實現這一點,火花應:
採取RDD用N網絡
鴻溝RDD成每個芯8個分區,每個分區具有N/8網絡
應用flatMap並行地將每個N/8網絡轉換爲N/8 * 10個新網絡。
在每臺機器上重複上述步驟,並行生成flatMap。
for循環結束後,每臺機器應該有10^9/8網絡。並行過濾它們,然後計算每臺機器上每個RDD中元素的數量,然後輸出答案。
這是我想實現的,但由於某些原因,for循環中的flatMap生成僅在一臺機器上完成。
我使用** conf.set(「spark.default.parallelism」,「8」)**使集羣使用所有8個核心,這就是爲什麼UI顯示8個任務,但只有一個真正的計數階段,這基本上是唯一的工作。正如你所看到的,我不使用文件作爲輸入,但我寧願使用flatMap在for循環的每次迭代中生成輸入。所以我真的不知道爲什麼for循環中的生成階段沒有並行運行。 –
我編輯了原始問題並添加了我想要實現的解釋。也許這有助於你理解發生了什麼,因爲我真的需要這個幫助。 –
如果在循環中使用「repartition」操作符會發生什麼情況。 – glefait