Resilient Distributed Datasets(RDDs),中文名称是弹性分布式数据集。Spark的所有操作围绕着RDDs展开。它是一组可容错的、可并行操作的数据的集合。我们可以通过两种方式来创建一个RDDs:
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
object RddTest {
def main(args: Array[String]): Unit = {
//1.创建sparkConf
val sparkConf:SparkConf = new SparkConf()
sparkConf.setAppName("RddTest")
sparkConf.setMaster("local")
//2.创建SparkContext
val sparkContext:SparkContext = new SparkContext(sparkConf)
//3.创建RDD
var array:Array[String] = Array("one","two","three","four","five","six"," ")
val numRdds:RDD[String] = sparkContext.parallelize[String](array,2)
//4.遍历打印RDD的元素
numRdds.foreach(println)
//5.关闭sparkContext
sparkContext.close()
}
}
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
case class SensorReading(id:String,timestamp:BigInt,temperature:Double)
object RddTest {
def myMapFunction(value:String):(String,Int)={
return (value,1)
}
def main(args: Array[String]): Unit = {
//1.创建sparkConf
val sparkConf:SparkConf = new SparkConf()
sparkConf.setAppName("RddTest")
sparkConf.setMaster("local")
//2.创建SparkContext
val sparkContext:SparkContext = new SparkContext(sparkConf)
val inpath:String = "D:\\javaworkspace\\BigData\\Spark\\SparkApp\\src\\main\\resources\\sensor.txt"
val rdd1:RDD[String] = sparkContext.textFile(inpath,2)
//过滤掉空的数据
val rdd2:RDD[String] = srcdata.filter(data=>{data.nonEmpty})
//将rdd2转换为Sensor
val rdd3:RDD[SensorReading] = rdd2.map(data=>{
val arr = data.split(",")
SensorReading(arr(0),arr(1).toLong,arr(2).toDouble)
})
rdd3.foreach(println)
//4.关闭sparkContext
sparkContext.stop()
}
}
RDD(Resilient Distributed Dataset),弹性分布式数据集。它具有以下5大特性:
要理解以上几点,我们先来看一张RDD的数据图:
在上面的示例中结合上图所示,我们基于文件使用sparkContext.TextFile()创建了一个RDD1,我们知道,在实际的运用场景中,我们的数据文件一般都是存放在HDFS文件系统中的。
我们知道,HDFS上的文件会被切割成一个个的Block(默认是128M),分布在不同的DataNode节点上。而RDD则是由一系列的Partition组成,默认情况下,一个Partition对应文件的一个Block(我们在创建RDD时可以通过参数指定Partition的个数,如上面代码中所示),如上图所示,因此RDD也是分布式的(不同的Partition分布在不同的节点上)。
由上图所示,我们可以很清晰的看到,RDD3依赖RDD2、RDD2依赖RDD1.所以说RDD之间是有依赖关系的(组成一个有向无环图DAG),另外很重要的一点,RDD实际是不存储整个block数据,或者说它不存储数据,只是封装了一个对数据的计算过程,数据实际是存放在HDFS的block上的。如RDD2.map对RDD2做算子运算时,会一步步向上追溯,读取block的一行,然后进行RDD1.filter()算子运算,计算完毕后将结果丢给RDD2.map的方法进行处理,然后输出结果。如图中不同RDD之间的数据传递是在内存中进行的,不涉及到文件IO。
我们知道,在大数据处理中,资源的最大消耗在于IO处理,所以原则上尽可能少的发生IO操作。而RDD是由partition组成,partition与文件的block对应。所以spark会在block所在的节点创建task来对数据进行处理,即数据本地化计算原则。