RDD(Resilient Distributed Dataset)弹性分布式数据集(“弹性”是指可以通过重新安排计算来自动重建丢失的分区)
是Spark最核心的概念,它是在一个集群中跨多个机器分区存储的一个只读对象集合。
在典型的Spark程序中,首先要加载一个或多个RDD,作为输入通过一系列转换得到一组目标RDD,然后对这些目标RDD执行一个动作,例如计算出结果或者写入持久存储器。
Spark和MapReduce一样有作业(job)的概念,不过Spark的作业比MapReduce更通用,因为Spark作业是由任意的多阶段有向无环图(DAG)构成,其中每个阶段大致相当于MapReduce中的map阶段或reduce阶段。
这些阶段又被Spark运行环境分解为多个任务(task),任务并行运行在分布于集群中的RDD分区上,就像MapReduce中的任务一样。
Spark作业始终运行在应用上下文(SparkContext实例)中,它提供了RDD分组以及共享变量。
RDD的创建有三种方法:
1)来自内存中的对象集合(也称为并行化一个集合)
2)使用外部存储器(HDFS等)中的数据集,RDD中没有真正要计算的数据,只记录了一下元数据。
3)对现有RDD进行转换
下面主要讲的第三种方法:
Spark给RDD提供了转换和动作两类操作。
转换是从现有RDD生成新的RDD;动作是触发对RDD的计算并对计算结果执行某种操作,返回给用户,或者保存到外部存储器中。转换是惰性的,动作则是立竿见影。
其实咱们想要判断一个操作是转换还是动作,可以通过观察它的返回类型,如果返回类型是RDD,则是转换,否则就是动作。
聚合转换
按键来对键-值对RDD进行聚合操作的三个主要转换函数:reduceByKey()、foleByKey()、aggregateByKey()。
这三个函数都是用于聚合给定键的值,并为每个键产生一个值。
reduceByKey()为键-值对中的值重复应用一个二进制函数,直至产生一个结果值。例如加法函数(_ + _)来聚合,即(3+1)+5=9。
foldByKey()相比于reduceByKey()要多提供一个零值,在做整数加法时它就是 0,相当于((0+3)+1)+5 = 9.。
aggregateByKey()可以改变聚类结果值得类型,例如将整数值聚合成一个集合。
5个属性:
1.一系列的分区(一个分区一定在一台机器上,一台机器上可以有多个分区)
2. 函数会作用到分区上
3. RDD之间存在依赖
4. 键-值对RDD 分区器 对应hash partition
5. RDD有一个最佳计算位置
持久化
即数据集存入内存,对于大规模作业来说,能节省时间。MapReduce则必须从磁盘中重新加载输入数据集。
持久化对于数据的交互式探索查询非常有用。
迭代算法中,上一次迭代计算的结果可以被缓存在内存中,以用作下一次迭代的输入。
spark也提供了不同级别的持久化行为,默认持久化级别是MEMORY_ONLY
MEMORY_ONLY_SER通过把分区中的元素序列化为字节数组来实现,多了一份CPU开销,减少垃圾回收压力。
MEMORY_AND_DISK如果数据集的大小不适合保存到内存中,就将其溢出到磁盘。
MEMORY_AND_DISK_SER如果序列化数据集的大小不适合保存到内存中,就将其溢出到磁盘。
序列化(补)
数据序列化和函数序列化
共享变量
Spark程序经常需要访问一些不属于RDD的数据。
广播变量
在经过序列化后被发送给各个executor,然后缓存在那里,以便后期任务可以在需要时访问它。
累加器
在任务中只能对它做加法的共享变量。