RDD它是Spark基,它是最根本的数据抽象。http://www.cs.berkeley.edu/~matei/papers/2012/nsdi_spark.pdf 它开着RDD文件。假设英语阅读太费时,:http://shiyanjun.cn/archives/744.html

本文也是基于这篇论文和源代码,分析RDD的实现。

第一个问题,RDD是什么?Resilient Distributed Datasets(RDD,) 弹性分布式数据集。RDD是仅仅读的、分区记录的集合。

RDD仅仅能基于在稳定物理存储中的数据集和其它已有的RDD上运行确定性操作来创建。这些确定性操作称之为转换。如map、filter、groupBy、join(转换不是程开发者在RDD上运行的操作)。

RDD不须要物化。RDD含有怎样从其它RDD衍生(即计算)出本RDD的相关信息(即Lineage)。据此能够从物理存储的数据计算出对应的RDD分区。

看一下内部实现对于RDD的概述:

Internally, each RDD is characterized by five main properties:
 *
 *  - A list of partitions
 *  - A function for computing each split
 *  - A list of dependencies on other RDDs
 *  - Optionally, a Partitioner for key-value RDDs (e.g. to say that the RDD is hash-partitioned)
 *  - Optionally, a list of preferred locations to compute each split on (e.g. block locations for
 *    an HDFS file)

每一个RDD有5个基本的属性:

  1. 一组分片(partition)。即数据集的基本组成单位
  2. 一个计算每一个分片的函数
  3. 对parent RDD的依赖,这个依赖描写叙述了RDD之间的lineage
  4. 对于key-value的RDD,一个Partitioner
  5. 一个列表,存储存取每一个partition的preferred位置。对于一个HDFS文件来说。存储每一个partition所在的块的位置。

org.apache.spark.rdd.RDD是一个抽象类,定义了RDD的基本操作和属性。这些基本操作包含map,filter和persist。另外。org.apache.spark.rdd.PairRDDFunctions定义了key-value类型的RDD的操作,包含groupByKey,join,reduceByKey,countByKey,saveAsHadoopFile等。org.apache.spark.rdd.SequenceFileRDDFunctions包含了全部的RDD都适用的saveAsSequenceFile。

RDD支持两种操作:转换(transformation)从现有的数据集创建一个新的数据集;而动作(actions)在数据集上运行计算后,返回一个值给驱动程序。 比如,map就是一种转换。它将数据集每一个元素都传递给函数。并返回一个新的分布数据集表示结果。

还有一方面,reduce是一种动作,通过一些函数将全部的元素叠加起来,并将终于结果返回给Driver程序。(只是还有一个并行的reduceByKey,能返回一个分布式数据集)

Spark中的全部转换都是惰性的。也就是说,他们并不会直接计算结果。相反的,它们仅仅是记住应用到基础数据集(比如一个文件)上的这些转换动作。

仅仅有当发生一个要求返回结果给Driver的动作时,这些转换才会真正运行。这个设计让Spark更加有效率的运行。比如。我们能够实现:通过map创建的一个新数据集。并在reduce中使用。终于仅仅返回reduce的结果给driver,而不是整个大的新数据集。

默认情况下,每一个转换过的RDD都会在你在它之上运行一个动作时被又一次计算。只是,你也能够使用persist(或者cache)方法,持久化一个RDD在内存中。在这种情况下,Spark将会在集群中,保存相关元素。下次你查询这个RDD时,它将能更高速訪问。在磁盘上持久化数据集。或在集群间复制数据集也是支持的。

下表列出了Spark中的RDD转换和动作。

每一个操作都给出了标识,当中方括号表示类型參数。前面说过转换是延迟操作。用于定义新的RDD;而动作启动计算操作,并向用户程序返回值或向外部存储写数据。

表1 Spark中支持的RDD转换和动作
转换 map(f : T ) U) : RDD[T] ) RDD[U]
filter(f : T ) Bool) : RDD[T] ) RDD[T]
flatMap(f : T ) Seq[U]) : RDD[T] ) RDD[U]
sample(fraction : Float) : RDD[T] ) RDD[T] (Deterministic sampling)
groupByKey() : RDD[(K, V)] ) RDD[(K, Seq[V])]
reduceByKey(f : (V; V) ) V) : RDD[(K, V)] ) RDD[(K, V)]
union() : (RDD[T]; RDD[T]) ) RDD[T]
join() : (RDD[(K, V)]; RDD[(K, W)]) ) RDD[(K, (V, W))]
cogroup() : (RDD[(K, V)]; RDD[(K, W)]) ) RDD[(K, (Seq[V], Seq[W]))]
crossProduct() : (RDD[T]; RDD[U]) ) RDD[(T, U)]
mapValues(f : V ) W) : RDD[(K, V)] ) RDD[(K, W)] (Preserves partitioning)
sort(c : Comparator[K]) : RDD[(K, V)] ) RDD[(K, V)]
partitionBy(p : Partitioner[K]) : RDD[(K, V)] ) RDD[(K, V)]
动作 count() : RDD[T] ) Long
collect() : RDD[T] ) Seq[T]
reduce(f : (T; T) ) T) : RDD[T] ) T
lookup(k : K) : RDD[(K, V)] ) Seq[V] (On hash/range partitioned RDDs)
save(path : String) : Outputs RDD to a storage system, e.g., HDFS

注意,有些操作仅仅对键值对可用,比方join。

另外。函数名与Scala及其它函数式语言中的API匹配。比如map是一对一的映射,而flatMap是将每一个输入映射为一个或多个输出(与MapReduce中的map相似)。

除了这些操作以外。用户还能够请求将RDD缓存起来。并且,用户还能够通过Partitioner类获取RDD的分区顺序。然后将还有一个RDD依照相同的方式分区。有些操作会自己主动产生一个哈希或范围分区的RDD,像groupByKey。reduceByKey和sort等。

从一个样例開始

以下的样例摘自RDD的论文,实现了处理一个HDFS日志文件里错误日志的逻辑。

lines = spark.textFile("hdfs://...")  // lines is a org.apache.spark.rdd.MappedRDD
errors = lines.filter(_.startsWith("ERROR")) // errors is a org.apache.spark.rdd.FilteredRDD
errors.cache() // persist 到内存中
errors.count() // 触发action。计算errors有多少个,即ERROR的多少行
// Count errors mentioning MySQL:
errors.filter(_.contains("MySQL")).count()
// Return the time fields of errors mentioning
// HDFS as an array (assuming time is field
// number 3 in a tab-separated format):
errors.filter(_.contains("HDFS"))
.map(_.split('\t')(3))
.collect()

spark是一个org.apache.spark.SparkContext的实例。基本上spark的应用都是以定义一个SparkContext開始的。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] = {
hadoopFile(path, classOf[TextInputFormat], classOf[LongWritable], classOf[Text],
minPartitions).map(pair => pair._2.toString).setName(path)
}

hadoopFile创建了一个org.apache.spark.rdd.HadoopRDD,而在HadoopRDD上调用map则生成了一个MappedRDD:

  /**
* Return a new RDD by applying a function to all elements of this RDD.
*/
def map[U: ClassTag](f: T => U): RDD[U] = new MappedRDD(this, sc.clean(f))

errors.cache()并不会马上运行,它的作用是在RDD的计算完毕后,将结果cache起来。以供以后的计算使用。这种话能够加快以后运算的速度。

errors.count() 就触发了一个action,这个时候就须要向集群提交job了:

 /**
* Return the number of elements in the RDD.
*/
def count(): Long = sc.runJob(this, Utils.getIteratorSize _).sum

提交后,SparkContext会将runJob提交到DAGScheduler。DAGScheduler会将当前的DAG划分成Stage。然后生成TaskSet后通过TaskScheduler的submitTasks提交tasks,而这又会调用SchedulerBackend。SchedulerBackend会将这些任务发送到Executor去运行。

怎样划分Stage?怎样生成tasks?接下来将得到解决。

为了明天还要上班,,早在今天休息吧。

版权声明:本文博主原创文章,博客,未经同意不得转载。

Spark里边:到底是什么RDD的更多相关文章

  1. Spark菜鸟学习营Day3 RDD编程进阶

    Spark菜鸟学习营Day3 RDD编程进阶 RDD代码简化 对于昨天练习的代码,我们可以从几个方面来简化: 使用fluent风格写法,可以减少对于中间变量的定义. 使用lambda表示式来替换对象写 ...

  2. Spark Streaming揭秘 Day18 空RDD判断及程序中止机制

    Spark Streaming揭秘 Day18 空RDD判断及程序中止机制 空RDD的处理 从API我们可以知道在SparkStreaming中,对于RDD的操作一般都是在foreachRDD和Tra ...

  3. Spark踩坑记——从RDD看集群调度

    [TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...

  4. 【Spark 深入学习 07】RDD编程之旅基础篇03-键值对RDD

    --------------------- 本节内容: · 键值对RDD出现背景 · 键值对RDD转化操作实例 · 键值对RDD行动操作实例 · 键值对RDD数据分区 · 参考资料 --------- ...

  5. Hive数据分析——Spark是一种基于rdd(弹性数据集)的内存分布式并行处理框架,比于Hadoop将大量的中间结果写入HDFS,Spark避免了中间结果的持久化

    转自:http://blog.csdn.net/wh_springer/article/details/51842496 近十年来,随着Hadoop生态系统的不断完善,Hadoop早已成为大数据事实上 ...

  6. 且谈 Apache Spark 的 API 三剑客:RDD、DataFrame 和 Dataset

    作者:Jules S. Damji 译者:足下 本文翻译自 A Tale of Three Apache Spark APIs: RDDs, DataFrames, and Datasets ,翻译已 ...

  7. Learning Spark中文版--第三章--RDD编程(1)

       本章介绍了Spark用于数据处理的核心抽象概念,具有弹性的分布式数据集(RDD).一个RDD仅仅是一个分布式的元素集合.在Spark中,所有工作都表示为创建新的RDDs.转换现有的RDD,或者调 ...

  8. Learning Spark中文版--第三章--RDD编程(2)

    Common Transformations and Actions   本章中,我们浏览了Spark中大多数常见的transformation(转换)和action(开工).在包含特定数据类型的RD ...

  9. Spark学习(一)--RDD操作

    标签(空格分隔): 学习笔记 Spark编程模型的两种抽象:RDD(Resilient Distributed Dataset)和两种共享变量(支持并行计算的广播变量和累加器). RDD RDD是一种 ...

随机推荐

  1. uva 10192 Vacation(最长公共子)

    uva 10192 Vacation The Problem You are planning to take some rest and to go out on vacation, but you ...

  2. 【程序猿助手】Emacs,最强的编辑器,之间的不

     wx_fmt=png" alt="" style="max-width:100%; height:auto!important"> 内容简单 ...

  3. CSS: 解决Div float后,父Div无法高度自适应的问题

    在用CSS+DIV的布局中,常常会发现,当一个DIV float之后,假设他的高度超过了其父DIV的高度时,其父DIV的高度并不会对应的进行调整.要解决问题(也叫做闭合(清除)浮动),我们有四种办法: ...

  4. (一个)kafka-jstorm集群实时日志分析 它 ---------kafka实时日志处理

    package com.doctor.logbackextend; import java.util.HashMap; import java.util.List; import java.util. ...

  5. 机械革命X5(MECHREVO MR-X5)开包检验

    不废话.直接的问题,左右X5没有更具体的信息.为了通过有机会了解后续的选择,具体的数据被释放约: 首先看包装: 1.快递包裹,基于卖方这可以是不同的,包装各不相同 watermark/2/text/a ...

  6. Storm具体的解释(二)、成为第一Storm申请书

         在全面介绍Storm之前,我们首先通过简单的Demo让我们来看看什么是整体感觉Storm. Storm执行模式: 本地模式(Local Mode): 即Topology(相当于一个任务,兴许 ...

  7. 快速排序:升序+降序----java实现

    快速排序思路:先把第一个元素令为low下标,最后一个为high下标.并把第一个元素令为temp来作为标准元素.以标准元素来调整数组,使比标准元素小的都在标准元素前,比标准元素大的都在标准元素后.这样一 ...

  8. HDU4866 Shooting (要持久段树)

    意甲冠军: 给你一些并行x行轴.总是询问坐标x的顶部之前,k一个段高度,.标题是必须在线. 思路: 首先要会可持久化线段树(又称主席树和函数式线段树).不会的能够去做下POJ 2104. 把全部线段高 ...

  9. 每位iOS开发人员不容错过的10大实用工具

    内容简介 1.iOS简介 2.iOS开发十大实用工具之开发环境 3.iOS开发十大实用工具之图标设计 4.iOS开发十大实用工具之原型设计 5.iOS开发十大实用工具之演示工具 6.iOS开发十大实用 ...

  10. DataGridView绑定数据源

    给DataGridView绑定数据源比較简单,方法主要有两种: 1.直接在控件属性中绑定数据源,这样的方法最简单,但它是直接连接数据库的,这样就和传DataTable的后果差点儿相同了,所以还是尽量避 ...