about云開發

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

打印 上一主題 下一主題

[小知識點] spark RDD分區是否可以指定分區

[復制鏈接]
跳轉到指定樓層
樓主
desehawk 發表于 2018-6-5 21:17:54 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式


spark可以指定分區如下面:通過partitionBy實現
val fileRDD = sc.textFile("/opt/tarballs/spark_kafka/beifengspark/src/main/scala/2015082818")
      .filter(line=>line.length>0)
      .map{
        line =>
          val arr = line.split("\t")
          val date = arr(17).substring(0,10)
          val guid = arr(5)
          val url = arr(1)
          val uid = arr(18)
          (uid,(guid,url)) //key-value:tuple2
      }.partitionBy(new HashPartitioner(10)) //采用了hashcode分片方式,分成了10份,十個分區,每個分區10分



本帖被以下淘專輯推薦:

沙發
 樓主| desehawk 發表于 2018-6-5 21:20:20 | 只看該作者
更多詳細內容


數據分區:

在分布式集群里,網絡通信的代價很大,減少網絡傳輸可以極大提升性能。

mapreduce框架的性能開支主要在io和網絡傳輸,io因為要大量讀寫文件,它是不可避免的,但是網絡傳輸是可以避免的,把大文件壓縮變小文件,從而減少網絡傳輸,但是增加了cpu的計算負載。

spark里面io也是不可避免的,但是網絡傳輸spark里面進行了優化:

spark把rdd進行分區(分片),放在集群上并行計算。

同一個rdd分片100個,10個節點,平均一個節點10個分區

當進行sum型的計算的時候,先進行每個分區的sum,然后把sum值shuffle傳輸到主程序進行全局sum,所以進行sum型計算對網絡傳輸非常小。

但對于進行join型的計算的時候,需要把數據本身進行shuffle,網絡開銷很大。

spark是如何優化這個問題的呢?

spark把key-value rdd通過key的hashcode進行分區,而且保證相同的key存儲在同一個節點上,這樣對改rdd進行key聚合時,就不需要shuffle過程

我們進行mapreduce計算的時候為什么要盡興shuffle?,就是說mapreduce里面網絡傳輸主要在shuffle階段,shuffle的根本原因是相同的key存在不同的節點上,按key進行聚合的時候不得不進行shuffle。shuffle是非常影響網絡的,它要把所有的數據混在一起走網絡,然后它才能把相同的key走到一起。要盡興shuffle是存儲決定的。

spark從這個教訓中得到啟發,spark會把key進行分區,也就是key的hashcode進行分區,相同的key,hashcode肯定是一樣的,所以它進行分區的時候100t的數據分成10分,每部分10個t,它能確保相同的key肯定在一個分區里面,而且它能保證存儲的時候相同的key能夠存在同一個節點上。

比如一個rdd分成了100份,集群有10個節點,所以每個節點存10份,每一分稱為每個分區,spark能保證相同的key存在同一個節點上,實際上相同的key存在同一個分區。

key的分布不均決定了有的分區大有的分區小。沒法分區保證完全相等,但它會保證在一個接近的范圍。

所以mapreduce里面做的某些工作里邊,spark就不需要shuffle了,spark解決網絡傳輸這塊的根本原理就是這個。

進行join的時候是兩個表,不可能把兩個表都分區好,通常情況下是把用的頻繁的大表事先進行分區,小表進行關聯它的時候小表進行shuffle過程。

大表不需要shuffle。

模版是:

val userData = sc.sequenceFile[UserID,UserInfo]("hdfs://...")

.partitionBy(new HashPartition(100))//構造100個分區

.persist()

從分區中獲益的操作:cogroup(), groupwith(),join(),leftOuterJoin(),rightOuterJoin(),groupByKey(),reduceByKey(),cobimeByKey(),lookup()

所有基于key的操作都會獲益

對于諸如cogroup()和join()這樣的二元操作,預先進行數據分區會讓其中至少一個rdd(使用已知分區器的那個rdd)不發生數據shuffle,如果兩個rdd使用同樣的分區方式,并且它們還緩存在同樣的機器上(比如一個rdd是通過mapvalues()從另一個rdd中創建出來的,這兩個rdd就會擁有相同的key和分區方式),或者其中rdd還沒有被計算出來,那么跨界點的shuffle(數據混洗)不會發生了。

mapreduce一般要求本地網卡達到20兆!即便進行了壓縮!

代碼:

[Scala] 純文本查看 復制代碼
import org.apache.hadoop.hive.ql.exec.persistence.HybridHashTableContainer.HashPartition
import org.apache.hadoop.mapred.lib
import org.apache.spark.SparkConf
import org.apache.spark.sql.SparkSession
import org.apache.spark.storage.StorageLevel
import org.apache.spark.HashPartitioner
/**
  * Created by zengxiaosen on 16/9/23.
  */
object PartitionVisitCount {

  /*
  大表小表關聯
   */
  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf().setAppName("useUDF").setMaster("local")
    val ss = SparkSession.builder().config(sparkConf).getOrCreate()
    val sc = ss.sparkContext

    val fileRDD = sc.textFile("/opt/tarballs/spark_kafka/beifengspark/src/main/scala/2015082818")
      .filter(line=>line.length>0)
      .map{
        line =>
          val arr = line.split("\t")
          val date = arr(17).substring(0,10)
          val guid = arr(5)
          val url = arr(1)
          val uid = arr(18)
          (uid,(guid,url)) //key-value:tuple2
      }.partitionBy(new HashPartitioner(10)) //采用了hashcode分片方式,分成了10份,十個分區,每個分區10分
      /*
      相同的key在同一個分區,在進行任務調用時候,大表不需要任何shuffle
      只需要shuffle小表
       */
      .persist(StorageLevel.DISK_ONLY)


    /*
    parallelize有兩個參數,第一個是他的list,第二個是分區數
    分區數可以不給,不給的情況下默認就是它的核數
     */
    //比如里面存的是我的用戶id
    val rdd = sc.parallelize(List(1,2,3,4,5,6,7),10)
      .map(i => (i+"", i+"str"))

    fileRDD.join(rdd).foreach(println)
    /*
    如果fileRDD后面還會關聯好多個其他的rdd1,rdd2。。。rddn
    就要先把大的fileRDD進行分區
    這樣優化了網絡傳輸

     */


  }

}









板凳
hahaxixi 發表于 2018-6-6 10:16:09 | 只看該作者
改版了,有點不習慣了
您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

關閉

推薦上一條 /4 下一條

QQ|小黑屋|about云開發-學問論壇|社區 ( 京ICP備12023829號 )

GMT+8, 2020-1-17 03:27 , Processed in 1.109375 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4 Licensed

© 2018 Comsenz Inc.Designed by u179

快速回復 返回頂部 返回列表
梭哈电子游艺 什么彩票网站源码 三张牌游戏下载 滴滴代驾赚钱不 澳洲幸运5 内蒙古时时彩昨天开奖 学生赚钱红包是真的吗 重庆快乐十分选号技巧 麦当劳靠这么赚钱 pk10不管怎么玩都是输 云南时时彩开奖时间 广东好彩1一彩乐乐 广西快乐十分 31选7今天开奖 代理什么麻将最赚钱 篮球比分网90 河北20选5走势图