深入解析spark RDD

弹性分布式数据集  RDD(只读,可分区)  这个数据集的部分或者全部可以缓存在内存中。

所谓弹性,是指内存不够时可以与磁盘进行交换。

RDD 作为数据结构,本质上是一个只读的分区记录集合。一个rdd可以包含多个分区,每个分区就是一个数据集片段。

宽依赖和窄依赖的区别:narrow dependecies 可以支持同一个cluster node 还是哪个以pipeline形式执行多条命令,如执行了map后可以继续filter,在失败恢复的时候只需要重新计算丢失的parent partition即可,而且可以并行的在不同的节点进行重计算。而shuffle dependencies 需要所有的父分区都可用,在失败恢复的时候牵涉个各级的多个parent partitions。

rdd的操作如上图两种,转换和动作。

rdd的四个核心方法:1 getPartitions   返回的是一系列partitions的集合,即一个partition类型的数组。

2 getDependencies  返回的是依赖关系的一个Seq集合,里面的Dependency数组中的下划线是类型的PlaceHolder(占位符)。

3  Compute 是针对RDD的每个partition进行计算的

4 getPreferredLocations是寻找partition的首选位置

通过调用SparkContext的parallelize方法,在一个已经存在的Scala集合上创建的(一个Seq对象)。集合的对象将会被拷贝,创建出一个可以被并行操作的分布式数据集。

spark-shell运行在集群上的方法  

下面小部分引用 https://blog.csdn.net/legotime/article/details/51871724  推荐看原文  特别不错  但有个别分区问题有待验证

外部读取参数textFile

/**
   * Read a text file from HDFS, a local file system (available on all nodes), or any
   * Hadoop-supported file system URI, and return it as an RDD of Strings.
   */
  def textFile(
      path: String,
      minPartitions: Int = defaultMinPartitions): RDD[String] = withScope {
    assertNotStopped()
    hadoopFile(path, classOf[TextInputFormat], classOf[LongWritable], classOf[Text],
      minPartitions).map(pair => pair._2.toString).setName(path)
  }

分析参数:
path: String 是一个URI,這个URI可以是HDFS、本地文件(全部的节点都可以),或者其他Hadoop支持的文件系统URI返回的是一个字符串类型的RDD,也就是是RDD的内部形式是Iterator[(String)]

minPartitions=  math.min(defaultParallelism, 2) 是指定数据的分区,如果不指定分区,当你的核数大于2的时候,不指定分区数那么就是 2

当你的数据大于128M时候,Spark是为每一个块(block)创建一个分片(Hadoop-2.X之后为128m一个block)

从本地系统读取整个文件夹

val path = "file:///usr/local/spark/spark-1.6.0-bin-hadoop2.6/licenses/"  //local file
val rdd1 = sc.textFile(path,2)
从本地系统中读取licenses这个文件夹下的所有文件
這里特别注意的是,比如這个文件夹下有35个文件,上面分区数设置是2,那么整个RDD的分区数是35*2?

這是错误的,這个RDD的分区数不管你的partition数设置为多少时,只要license這个文件夹下的這个文件a.txt

(比如有a.txt)没有超过128m,那么a.txt就只有一个partition。那么就是说只要这35个文件其中没有一个超过

128m,那么分区数就是 35个

对spark输出结果进行排序(广告点击与商品排名)

  def sortByKey(ascending: Boolean = true, numPartitions: Int = self.partitions.length) : RDD[(K, V)] = self.withScope
  {
    val part = new RangePartitioner(numPartitions, self, ascending)
    new ShuffledRDD[K, V, V](self, part)
      .setKeyOrdering(if (ascending) ordering else ordering.reverse)
  }

union操作:

结果

groupByKey :

结果:

join操作实际上就是一个笛卡尔积的操作  

下面介绍Action操作:

reduce  

lookup的使用:

结果:

rdd.toDebugString 可以查看lineage关系

猜你喜欢

转载自blog.csdn.net/IT_NEU_Lee/article/details/84717124