什么是RDD
RDD是弹性分布式数据集的简称,她具有以下的优点:第一RDD具有并行化的操作特点,通俗的说,在RDD中存在一定数量的分片,每一个分片都会对应一个task,这些Task是可以并发烦人执行。第二,RDD具有很好的容错处理,这个特性是由RDD的血统依赖产生的,RDD1---->RDD2---->RDD3,这单个RDD一次又前面的那产生,同事RDD又具有不变的性质,当RDD3发生执行的错误,是可以由RDD2来直接再次生产。RDD的可以由两种方法产生,第一,并行化当前程序中的数据集或者引用外部的数据集HDFS,HBASE上面的数据集。
并行化数据集
我们可以手动的创建一个数据集合Array,然后就Spark会把数据集拷贝到集群上去,进行并行化的处理。这里我们需要关心的是spark到底会把我们的数据集怎样划分呢?具体的会划分成为多少个数据集呢?spark会在每一个partition上面执行一个Task,你可以手动的设置这个并行化的个数,也可以让spark自己来自动按照当前集群的硬件信息来得到的。
val data = Array(1, 2, 3, 4, 5)
val distData = sc.parallelize(data)
引用外部数据集
spark可以在任何支持hadoop的输入数据格式上创建分布是数据集例如Cassandra, HBase。spark支持文本txt格式,二进制格式,hadoopInputformat格式的数据输入。
</pre><pre name="code" class="python">scala> val distFile = sc.textFile("data.txt")
distFile: RDD[String] = MappedRDD@1d4cee08
spark的sparkContxet方法大多数情况用于从hdfs上面读取相应的文件。我们可以看到data.txt备当做RDD[String].从而产生一个mappedRDD.这种事由现有的RDD经过transformation来得到的,这种操作性质是一个懒加载的过程。只有遇到active的时候才会去执行。
这个数据集一旦被创建成功,spark就会在这个数据上进行相应的操作,例如去统计当前数据所有行的大小加起来。distFile.map(s => s.length).reduce((a, b) => a + b)
.。后面我们再去详细 的解释这些高阶函数的具体用处。
需要注意的是;first数据集参数必须是在每一个worker node上具有相同的目录,或者把当前的数据集拷贝到每一个节点的目录下面去。second,textFile这个函数是支持文件目录,压缩文件,文本文件作为参数的。third,该函数还有一个参数,并行化数据,你可以手动的添加,也可以让spark根据集群的硬件信息去选择。
RDD这个接口是如何实现的
该图片是从spark的源代码中截取的。我们可以看到spark非常重要的三个特性,其中还包括两个可选择项目
我们可以看到最主要的三个是什么,包括一系列的partition,每一个partition都会有一个相应的task去执行任务,作用于每一个分片对应执行的函数体,为了容错而产生的RDD依赖,这类分为宽依赖和窄依赖。其余的两个可算则项目partitioner,就是如何把相同的的key放到一块,还有一个为了提高执行的效率而产生的数据本地化,就是说找到当前RDD执行的最优位置。说了这么多。我们来来看看RDD的源代码吧
abstract class RDD[T: ClassTag](
@transient private var _sc: SparkContext,
@transient private var deps: Seq[Dependency[_]]
) extends Serializable with Logging {<span style="color:#ff0000;">
</span>
我们看到RDD是一个抽象类。含有两最主要的参数,sparkContxet是外部程序进入spark的唯一通道。deps就是锁对应的依赖,也就是上一个RDD是什么,由此形成了血统。我看一下下面的这个图片,是RDD中的各种方法,
第一个方法comput:由子类去具体的实现,主要对应于RDD的第一个特性,就是执行每一个sparkRDD分片的函数。getPartitions函数就是得到对应RDD的分片。getDependces函数就是得到对应的依赖。getPreferedLoactions就是得到最佳的执行位置。