Java Spark 簡單示例(七) RDD分區 分區劃分器

大數據學習交流微信群

更多RDD的信息參考:https://www.cnblogs.com/qingyunzong/p/8899715.html

分區

Spark程序中,RDD是由SparkContext上下文生成的,一個數據源只能生成一個RDD對象(流處理場景中,指定多個消息源可以生成多個RDD,存在DStream中)。

RDD(Resilient Distributed Dataset)Spark中最基本的數據抽象,它代表一個不可變、可分區、里面的元素可并行計算的集合。

分區(Partition),即數據集的基本組成單位。對于RDD來說,每個分區都會被一個計算任務Task處理,并決定并行計算的粒度。用戶可以在創建RDD時指定RDD的分區個數,如果沒有指定,那么就會采用默認值。默認值就是程序所分配到的CPU Core的數目(取決于運行環境)。如果是從HDFS中創建,默認為文件的數據塊數。

分區劃分器

Spark默認提供兩種劃分器:哈希分區劃分器(HashPartitioner)和范圍分區劃分器(RangePartitioner),且Partitioner只存在(K, V)類型的RDD中,對于非(K, V)類型的Partitioner值為None

//從test.txt 構建rdd
JavaRDD<String> rdd = sc.textFile("test.txt");
System.out.println("初始分區劃分器:" + rdd.partitioner().toString());

輸出:初始分區劃分器:Optional.empty

HashPartitioner 是默認分區劃分器,他的原理是對于給定的key,計算其hashCode,并除于分區的個數取余,如果余數小于0,則用余數+分區的個數,最后返回的值就是這個key所屬的分區ID。但HashPartitioner易造成分區內數據不均勻(跟key的分布息息相關)。

RangePartitioner分區劃分器可以解決數據分布不均勻問題,他能保證分區與分區之間是有序的,一個分區中的元素肯定都是比另一個分區內的元素小或者大,但是分區內的元素是不能保證順序的。簡單的說就是將一定范圍內的數映射到某一個分區內。

groupByKey()默認采用哈希分區劃分器,當然也可以手動指定分區劃分器(包括自定義分區劃分器)

pairRDD.groupByKey(4); //默認哈希分區劃分器,并指定分區數=4
OR
pairRDD.groupByKey(new HashPartitioner(4)); //指定哈希分區劃分器,并指定分區數=4

<K,V>結構的RDD,還可以手動使用分區劃分器,使用partitionBy(Partitioner partitioner)函數

JavaPairRDD<String, Iterable<Integer>> groupRDD = pairRDD.groupByKey();
System.out.println("partitionBy前初始分區劃分器:" + groupRDD.partitioner().toString());
groupRDD.partitionBy(new HashPartitioner(3)); //手動使用分區劃分器
System.out.println("partitionBy后初始分區劃分器:" + groupRDD.partitioner().toString());

請注意:如果rdd當前分區劃分器與partitionBy指定的劃分器相同,則不再進行分區劃分,因此上述代碼輸出為

partitionBy前初始分區劃分器:Optional[org.apache.spark.HashPartitioner@4]
partitionBy后初始分區劃分器:Optional[org.apache.spark.HashPartitioner@4]

為了證明partitionBy指定HashPartitioner分區器沒有生效,我們改變一下分區數,并打印

JavaPairRDD<String, Iterable<Integer>> groupRDD = pairRDD.groupByKey(2); //指定分區數2
System.out.println("partitionBy前分區數:" + groupRDD.getNumPartitions());
groupRDD.partitionBy(new HashPartitioner(4)); //指定分區數4
System.out.println("partitionBy后分區數:" + groupRDD.getNumPartitions());
輸出:
partitionBy前分區數:2
partitionBy后分區數:2

指定分區的方法

并行化創建(創建rdd時指定)。指定生成n個分區的rdd

// 構造數據源
List<Integer> data = Arrays.asList(1, 2, 3, 4, 5);
//并行化創建rdd
JavaRDD<Integer> rdd = sc.parallelize(data,n); 

文件中創建(創建rdd時指定)。指定生成n個分區的rdd

//從test.txt 構建rdd
JavaRDD<String> rdd = sc.textFile("test.txt",n); 

shuffle時指定。指定shuffle后新的rdd的分區數(n在最后)

JavaPairDStream<String, Integer> wordCounts = pairs.reduceByKey(new Function2<Integer, Integer, Integer>() {
        public Integer call(Integer integer, Integer integer2) throws Exception {
            return integer + integer2;
        }
},n); 

指定默認配置請注意:此方式僅對shuffle后的rdd有效。即如果沒有在創建rdd時指定分區數,該配置不會修改初始rdd的分區數,但是對shuffle后的新rdd有效。

補充:我之前有個疑問就是如果不指定分區,shuffle前和shuffle后的分區是不是變化的,經過本地測試,答案是會變化。

conf.set("spark.default.parallelism","n");

本地模式。貌似也只對并行化創建rdd有效,本地demo設置local[*],打印從文件中創建的rdd分區數結果是2。這種方式不用太在意,本地只是測試用。

new SparkConf().setMaster(local[n]); //n 表示具體的分區數
或
new SparkConf().setMaster(local[*]); //*表示使用cpu core 數

腳本模式。沒研究

  • Spark-shell --conf <key>=<value>
  • Spark-submit --conf <key>=<value>

綜上
建議直接在操作rdd的函數中指定分區數,不僅優先級最高,而且保證準確性。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,958評論 2 373

推薦閱讀更多精彩內容