Spark-Core
介绍
计算引擎,类似MapReduce,将数据存放在内存中,减少磁盘IO,他是有scala编写的
总体技术栈讲解
-
Spark Streaming
- 流式计算框架
-
Spark GraphX
- 图形计算引擎
-
ML Base
- 机器学习
-
Spark SQL
- 使用SQL处理业务
优点
-
更快
-
易于使用
- Spark Sql
-
支持多种环境
运行模式
-
Local
- 多用于本地测试,如在 eclipse , idea 中写程序测试等。
-
Standalone
- Standalone 是 Spark 自带的一个资源调度框架,它支持完全分布式。
-
Yarn
- Hadoop 生态圈里面的一个资源调度框架, Spark 也是可以基于 Yarn 来计算的。
与MapReduce的区别
spark基于内存,MapReduce基于硬盘
两者迭代式计算的速度相差很大
分区和RDD
Partition
-
概念
- Spark RDD 是一种分布式的数据集,由于数据量很大,因此要它被切分并存储在各个结点的分区当中。
- Spark中,RDD(Resilient Distributed Dataset)是其最基本的抽象数据集,其中每个RDD是由若干个Partition组成。
- RDD1包含了5个Partition,RDD2包含了3个Partition,这些Partition分布在4个节点中。
-
分区方式
-
Spark包含两种数据分区方式:HashPartitioner(哈希分区)和RangePartitioner(范围分区)
-
HashPartitioner
- Hash分区
- HashPartitioner采用哈希的方式对<Key,Value>键值对数据进行分区。
- 其数据分区规则为 partitionId = Key.hashCode % numPartitions
-
RangePartitioner
- 范围分区
- Spark引入RangePartitioner的目的是为了解决HashPartitioner所带来的分区倾斜问题,也即分区中包含的数据量不均衡问题。
- HashPartitioner采用哈希的方式将同一类型的Key分配到同一个Partition中,当某几种类型数据量较多时,就会造成若干Partition中包含的数据过大
- 在Job执行过程中,一个Partition对应一个Task,此时就会使得某几个Task运行过慢。
- RangePartitioner基于抽样的思想来对数据进行分区
-
RDD
-
弹性分布式数据集
-
RDD五大属性
- RDD 是由一系列的 partition 组成的。
- 函数是作用在每一个 partition/split 上。
- RDD 之间有一系列的依赖关系。
- 分区器是作用在 (K,V) 格式的 RDD 上。
- RDD 提供一系列最佳的计算位置。
-
RDD流程图
-
Lineage血统
- RDD 的最重要的特性之一就是血缘关系(Lineage ),它描述了一个 RDD 是如何从父 RDD 计算得来的。如果某个 RDD 丢失了,则可以根据血缘关系,从父 RDD 计算得来。
多文件算子
转换算子
-
转换算组join
- leftOuterJoin
- rightOuterJoin
- fullOuterJoin
- join 后的分区数与父RDD分区数多的那一个相同。
-
union
- 合并两个数据集。两个数据集的类型要一致。
- 返回新的 RDD 的分区数是合并 RDD 分区数的总和。
-
intersection
- 取两个数据集的交集。
- 分区数为最多分区数的RDD,不可设置
-
subtract
- 取两个数据集的差集。
- 分区数与前面那个RDD的分区相似
-
mapPartitions
- mapPartition与 map 类似,单位是每个 partition 上的数据。
- 分区数不变
-
distinct(map+reduceByKey+map)
- 对 RDD 内数据去重。
- 分区数不变
-
cogroup
- 当调用类型 (K,V) 和 (K,W) 的数据上时,返回一个数据集 (K,(Iterable,Iterable)) 。
- 分区数为最多分区数的RDD的分区数
行动算子
-
foreachPartition
- 遍历所有分区的数据
窄依赖和宽依赖
窄依赖
- 父 RDD 和子 RDD 的 partition 之间的关系是一对一的。或者父 RDD 和子 RDD 的 partition 关系是多对一的。不会有 shuffle 的产生。
宽依赖
- 父 RDD 与子 RDD 的 partition 之间的关系是一对多。会有 shuffle 的产生
宽窄依赖图理解
Stoge
概念
- 阶段
- 多个连续的窄依赖的或者不存在shuffle的RDD为一个Stoge
- 将这个阶段中的partition放在同一个节点中,减少数据的传输
- 一个stage的task处理的Partition之间全是窄依赖
stage切割规则
-
1.从后向前推理,遇到宽依赖就断开,遇到窄依赖就把当前的RDD加入到Stage中;
-
2.每个Stage里面的Task的数量是由该Stage中最后一个RDD的Partition数量决定的;
-
3.最后一个Stage里面的任务的类型是ResultTask,前面所有其他Stage里面的任务类型都是ShuffleMapTask;
-
4.代表当前Stage的算子一定是该Stage的最后一个计算步骤;
-
总结
- 由于spark中stage的划分是根据shuffle来划分的,而宽依赖必然有shuffle过程,因此可以
说spark是根据宽窄依赖来划分stage的。
- 由于spark中stage的划分是根据shuffle来划分的,而宽依赖必然有shuffle过程,因此可以
SparkShuffle
HashShuffle
-
普通模式
- 上游产生数据的时候,根据下游的Partition生成文件
- 总生成的文件数为:MapTask * ReduceTask
-
合并模式
- 每一个Executor创建一批(下游Partition的数量)文件
- 文件数量:MapExecutor * ReduceTask
SortShuffle
- map产生中间结果,写出到KvBuffer–分区排序–溢写–合并
- 产生MapTask*2个文件
- bypass
- reduceTask数量不足200个
分区算子
转换算子
-
mapPartitionsWithIndex
- 类似于 mapPartitions ,除此之外还会携带分区的索引值。
-
repartition
- 增加或减少分区。此算子会产生 shuffle 。
-
coalesce
- coalesce 常用来减少分区,算子中第二个参数是减少分区的过程中是否产生 shuffle 。
- true 为产生 shuffle , false 不产生 shuffle 。默认是 false 。
- 如果 coalesce 设置的分区数比原来的 RDD 的分区数还多的话,第二个参数设置为 false 不会起作用(转换之后分区数大于之前),如果设置成 true ,效果和 repartition 一样。
- repartition(numPartitions) = coalesce(numPartitions,true)
-
groupByKey
- 作用在 K,V 格式的 RDD 上。根据 Key 进行分组。作用在 (K,V) ,返回 (K,Iterable) 。
-
zip
- 将两个 RDD 中的元素( KV格式/非KV格式 )变成一个 KV 格式的 RDD ,两个 RDD 的个数必须相同。
-
zipWithIndex
- 该函数将 RDD 中的元素和这个元素在 RDD 中的索引号(从0开始)组合成 (K,V) 对。
行动算子
-
countByKey
- 作用到 K,V 格式的 RDD 上,根据 Key 计数相同 Key 的数据集元素。
-
countByValue
- 根据数据集每个元素相同的内容来计数。返回相同内容的元素对应的条数。
-
reduce
- 根据聚合逻辑聚合数据集中的每个元素。
案例
PV&UV
二次排序
分组取topN
广播变量和累加器
spark提供的源码级别的提高任务间读写效率的功能
广播变量
- 减少变量副本数(网络传输)
- 同个进程(executor)中的多个task共用同一个广播变量
累加器
- Driver端定义的变量,发送到executor中发生改变会同步到Driver端
算子
转换算子
-
类算子叫做转换算子(本质就是函数), Transformations 算子是延迟执行,也叫懒加载执行。需要行动算子才能执行
-
常用转换算子
-
filter
- 过滤
-
flatMap
- 拆分
-
map
- 对每个元素进行修改获得个新的集合
-
reduceByKey
- 合并
-
sortBy
- 排序
-
行动算子
-
执行别的算子所需要的算子
-
常见
-
count
- 返回数据集中的元素数。会在结果计算完成后回收到 Driver 端
-
foreach
- 循环遍历数据集中的每个元素,运行相应的逻辑。
-
take
- 返回一个包含数据集前 n 个元素的集合。
-
first
- 效果等同于 take(1) ,返回数据集中的第一个元素。
-
collect
- 将计算结果回收到 Driver 端。
-
控制算子
-
持久化RDD,单位是Partition
-
三种
-
cache
- 持久化在内存中,cache 是懒执行
-
persist
- 自行选择缓存级别
- MEMORY_ONLY 和 MEMORY_AND_DISK
-
checkpoint
-
checkpoint 将 RDD 持久化到磁盘,还可以切断 RDD 之间的依赖关系,也是懒执行。
-
执行原理
- 当 RDD 的 job 执行完毕后,会从 finalRDD 从后往前回溯。
- 当回溯到某一个 RDD 调用了 checkpoint 方法,会对当前的 RDD 做一个标记。
- Spark 框架会自动启动一个新的 job ,重新计算这个 RDD 的数据,将数据持久化到Checkpint目录中。
-
使用 checkpoint 时常用优化手段
- 对 RDD 执行 checkpoint 之前,最好对这个 RDD 先执行 cache
- 这样新启动的 job 只需要将内存中的数据拷贝到Checkpint目录中就可以,省去了重新计算这一步。
-
-