更新時(shí)間:2021-01-29 來源:黑馬程序員 瀏覽量:
在分布式程序中,網(wǎng)絡(luò)通信的開銷是很大的,因此控制數(shù)據(jù)分布以獲得最少的網(wǎng)絡(luò)傳輸開銷可以極大地提升整體性能.Spark程序可以通過控制RDD分區(qū)方式來減少通信開銷。Spark中所有的RDD都可以進(jìn)行分區(qū),系統(tǒng)會(huì)根據(jù)一個(gè)針對(duì)鍵的函數(shù)對(duì)元素進(jìn)行分區(qū)。雖然Spark不能控制每個(gè)鍵具體劃分到哪個(gè)節(jié)點(diǎn)上,但是可以確保相同的鍵出現(xiàn)在同一個(gè)分區(qū)上。RDD的分區(qū)原則是分區(qū)的個(gè)數(shù)盡量等于集群中的CPU核心(Core)數(shù)目。對(duì)于不同的Spark部署模式而言,都可以通過設(shè)置spark.default.prallien這個(gè)參數(shù)值來配置默認(rèn)的分區(qū)數(shù)目。一般而言,各種模式下的默認(rèn)分區(qū)數(shù)目如下。
(1) Local模式:默認(rèn)為本地機(jī)器的CPU數(shù)目,若設(shè)置了loca[N],則默認(rèn)為N。
(2) Standalone或者Yarn模式:在“集群中所有CPU核數(shù)總和”和“2”這兩者中取較大值作為默認(rèn)值。
(3) Mesos 模式:默認(rèn)的分區(qū)數(shù)是8。
Spark框架為RDD提供了兩種分區(qū)方式,分別是哈希分區(qū)(HashPartitioner)和范圍分區(qū)(RangePartitioner)。其中,哈希分區(qū)是根據(jù)哈希值進(jìn)行分區(qū);范圍分區(qū)是將一定范圍的數(shù)據(jù)映射到一個(gè)分區(qū)中。這兩種分區(qū)方式已經(jīng)可以滿足大多數(shù)應(yīng)用場景的需求。與此同時(shí),Spark也支持自定義分區(qū)方式,即通過一個(gè)自定義的Partitioner對(duì)象來控制RDD的分區(qū),從而進(jìn)一步減少通信開銷。 需要注意的是,RDD的分區(qū)函數(shù)是針對(duì)(Key, Value)類型的RDD,分區(qū)函數(shù)根據(jù)Key對(duì)RDD元素進(jìn)行分區(qū)。因此,當(dāng)需要對(duì)一些非(Key,Value)類型的RDD進(jìn)行自定義分區(qū)時(shí),需要先把RDD元素轉(zhuǎn)換為(Key,Value)類型,再通過分區(qū)函數(shù)進(jìn)行分區(qū)操作。
如果想要實(shí)現(xiàn)自定義分區(qū),就需要定義一個(gè)類,使得這個(gè)自定義的類繼承org. apache.spark. Partitioner類,并實(shí)現(xiàn)其中的3個(gè)方法,具體如下。
(1) def numPartitions:Int:用于返回創(chuàng)建的分區(qū)個(gè)數(shù)。
(2) def getPartition(Key:Any):用于對(duì)輸人的Key做處理,并返回該Key的分區(qū)ID,分區(qū)ID的范圍是0~ numPartitions 1。
(3) equals (other: Any):用于Spark判斷自定義的Partitioner對(duì)象和其他的Partitioner 對(duì)象是否相同,從而判斷兩個(gè)RDD的分區(qū)方式是否相同。其中,equals()方法中的參數(shù)other表示其他的Partitioner 對(duì)象,該方法的返回值是一個(gè)Boolean類型,當(dāng)返回值為true時(shí)表示自定義的Pritioer對(duì)象和其他Pritioer對(duì)象相同,則兩個(gè)RDD的分區(qū)方式也是相同的;反之,自定義的Pritoner對(duì)象和其他Prtitioer對(duì)象不相同,則兩個(gè)RDD的分區(qū)方式也不相同。
猜你喜歡:
RDD轉(zhuǎn)換算子API過程演示【大數(shù)據(jù)文章】