Spark简介
Spark是专为大规模数据处理而设计的快速通用的计算引擎;
Spark拥有Hadoop MapReduce所具有的优点,但是运行速度却比MapReduce有很大的提升,特别是在数据挖掘、机器学习等需要迭代的领域可提升100x倍的速度:
- Spark是基于内存进行数据处理的,MapReduce是基于磁盘进行数据处理的;
- Spark中具有DAG有向无环图,DAG有向无环图在此过程中减少了shuffle以及落地磁盘的次数;
Spark流程
- Spark Application的运行环境:创建SparkConf对象
-
- 可以设置Application name;
- 可以设置运行模式及资源需求;
- 创建SparkContext对象;
-
- SparkContext向资源管理器申请运行Executor资源,并启动StandaloneExecutorbackend;
- Executor向SparkContext申请Task;
- SparkContext将程序分发给Executor;
- SparkContext构建成DAG图,将DAG图分解成Stage、将Taskset发送给Task Scheduler,最后由Task Scheduler将Task发送给Executor运行;
- Task在Excutor上运行,运行完释放所有的资源;
- 基于Spark的上下文创建一个RDD,对RDD进行处理;
- 应用程序中y有Action累算子来触发Transformation类算子执行;
- 关闭Spark上下文对象SparkContext;
value 类型
细类型 | 算子 |
---|---|
输入分区与输出分区一对一型 | map flatMap mapPartitions glom |
输入分区与输出分区多对一型 | union cartesain |
输入分区与输出分区多对多型 | groupBy |
输出分区为输入分区子集型 | filter distinct substract sample takeSample |
Cache型 | cache persist |
key-value类型
细类型 | 算子 |
---|---|
输入分区与输出分区一对一 | mapValues |
对单个RDD或两个RDD聚集 | 单个RDD聚集: combineByKey reduceByKey partitionBy; 两个RDD聚集: Cogroup |
连接 | join leftOutJoin和 rightOutJoin |
Action算子
细类型 | 算子 |
---|---|
无输出 | foreach |
HDFS | saveAsTextFile saveAsObjectFile |
Scala集合和数据类型 | collect collectAsMap reduceByKeyLocally lookup count top reduce fold aggregate |
转换算子(Transformations)
不触发提交作业,只是完成作业中间过程处理;Transformation 操作是延迟计算的,也就是说从一个RDD 转换生成另一个 RDD 的转换操作不是马上执行,需要等到有 Action 操作的时候才会真正触发运算。Transformation参数类型为value或者key-value的形式;
转换算子是延迟执行的,也叫懒加载执行
map
将原来RDD的每个数据通过map中的用户自定义函数映射为一个新的元素,源码中map算子相当于初始化一个RDD --------- f(x)=x -> y
- scala源码
def map[U: ClassTag](f: T => U): RDD[U] = withScope { val cleanF = sc.clean(f) new MapPartitionsRDD[U, T](this, (context, pid, iter) => iter.map(cleanF)) }
flatMap
将原来 RDD 中的每个元素通过函数 f 转换为新的元素,并将生成的 RDD 的每个集合中的元素合并为一个集合,内部创建 FlatMappedRDD(this,sc.clean(f))。 ------ f: T => TraversableOnce[U]
-
scala源码
def flatMap[U: ClassTag](f: T => TraversableOnce[U]): RDD[U] = withScope { val cleanF = sc.clean(f) new MapPartitionsRDD[U, T](this, (context, pid, iter) => iter.flatMap(cleanF)) }
-
例子
lines.flatMap{lines => { lines.split(" ")
mapPartitions
mapPartitions 函 数 获 取 到 每 个 分 区 的 迭 代器,在 函 数 中 通 过 这 个 分 区 整 体 的 迭 代 器 对整 个 分 区 的 元 素 进 行 操 作。 内 部 实 现 是 生 成 -------f (iter)=>iter.f ilter(_>=3)
-
scala源码
def filter(f: T => Boolean): RDD[T] = withScope { val cleanF = sc.clean(f) new MapPartitionsRDD[T, T]( this, (context, pid, iter) => iter.filter(cleanF), preservesPartitioning = true) }
glom
glom函数将每个分区形成一个数组,内部实现是返回的GlommedRDD。 图4中的每个方框代表一个RDD分区。图4中的方框代表一个分区。 该图表示含有V1、 V2、 V3的分区通过函数glom形成一数组Array[(V1),(V2),(V3)]
-
scala源码
def glom(): RDD[Array[T]] = withScope { new MapPartitionsRDD[Array[T], T](this, (context, pid, iter) => Iterator(iter.toArray)) }
union
使用 union 函数时需要保证两个 RDD 元素的数据类型相同,返回的 RDD 数据类型和被合并的 RDD 元素数据类型相同,并不进行去重操作,保存所有元素。如果想去重可以使用 distinct()(并集)
-
scala源码
def union(other: RDD[T]): RDD[T] = withScope { sc.union(this, other) }