2016-05-29 72 views
5

我有一個約10個平面文件的應用程序,每個文件的值都超過200MM +記錄。業務邏輯涉及順序連接所有這些邏輯。Spark RDD - 避免混洗 - 分區有助於處理大文件嗎?

我的環境: 1主 - 3個從站(用於測試我已經分配了一個1GB存儲器到每個節點)

大多數代碼只是做了如下爲每個加入

RDD1 = sc.textFile(file1).mapToPair(..) 

RDD2 = sc.textFile(file2).mapToPair(..) 

join = RDD1.join(RDD2).map(peopleObject) 

任何建議調整,如重新分區,並行化..?如果是的話,有什麼最好的做法,以獲得良好的重新分區號碼?

與當前的配置工作需要一個多小時,我看到洗牌寫的幾乎每一個文件> 3GB

+0

文件:基本原理是從星火UI採取以下美麗的PIC呈現的?你有多少個分區? – marios

+0

沒有。他們在aws s3中並沒有做任何分區,但內部可能會使用默認並行機制。 – sve

+0

你可以做RDD1.partitions.size或運行「RDD1.toDebugString」,看看你有多少個分區? – marios

回答

2

如果我們總是加入一個RDD(比如RDD1集)與所有其他的想法是分區該RDD,然後堅持它。

這裏是須藤-Scala實現(可以很容易地轉換到Python或Java):

val rdd1 = sc.textFile(file1).mapToPair(..).partitionBy(new HashPartitioner(200)).cache() 

到這裏爲止,我們有RDD1集被散列到200個分區。第一次將被評估它將被持久(緩存)。

現在讓我們讀兩個rdds並加入它們。

val rdd2 = sc.textFile(file2).mapToPair(..) 
val join1 = rdd1.join(rdd2).map(peopleObject) 
val rdd3 = sc.textFile(file3).mapToPair(..) 
val join2 = rdd1.join(rdd3).map(peopleObject) 

請注意,對於重新生成的RDD,我們不會對它們進行分區,也不會緩存它們。

Spark會看到rdd1已經是散列分區,它將爲所有剩餘的連接使用相同的分區。因此,rdd2和rdd3會將其密鑰洗牌到rdd1密鑰所在的相同位置。

爲了使它更清楚,讓我們假設我們不做分區,並使用問題所示的相同代碼;每次我們進行連接時,兩個rdds都將被洗牌。這意味着如果我們有n個連接到rdd1,那麼非分區版本會將rdd1轉換N次。分區方法只會將rdd1洗牌一次。

+0

我們通過緩存第一個RDD獲得了什麼? – axiom

+0

當所有的鑰匙找到他們的家時,他們會一直呆在那裏,直到你完成了所有的加入。 – marios

+0

當第一次連接被調用時,'rdd1'將實現一次。它將從此以後被緩存,但它也不會隨後被使用(按照OP的給定代碼)。在連接完成之前,我們不需要'rdd1'。我看到你提出了一個稍微不同的用例。 OP想要rdd1.join(rdd2)....加入(rddN)IMO。緩存無疑對您的答案中提供的代碼有用。 – axiom

3

在實踐中,對於大數據集(每個5,100G +),我已經看到,當您開始加入它們之前,共同分割一系列連接中涉及的所有RDD時,連接效果最佳。

RDD1 = sc.textFile(file1).mapToPair(..).partitionBy(new HashPartitioner(2048)) 

RDD2 = sc.textFile(file2).mapToPair(..).partitionBy(new HashPartitioner(2048)) 
. 
. 
. 
RDDN = sc.textFile(fileN).mapToPair(..).partitionBy(new HashPartitioner(2048)) 

//start joins 

RDD1.join(RDD2)...join(RDDN)


附註: 我指的是這種類型的加入成爲一棵樹加入(RDD每使用一次)。存儲在HDFS

enter image description here

+0

/@ mario - 一個簡單的解釋。事實上,我有兩個用例將RDD1與其他RDD順序連接,並將RDDn1,RDDn2和RDD1的結果連接起來。看看提供的示例,我的理解是,當我劃分所有RDD並緩存主RDD時,性能會更好。讓我知道,如果我得到這個權利。 – sve

+0

@SpringStarter請注意,在上面提到的情況下,緩存實際上會受到傷害,因爲您在不需要的東西上浪費空間。但是,對於您提到的其他用例,緩存確實會有所幫助。 – axiom