Spark
一、背景
MapReduce的局限性
- 仅支持Map,Reduce两种语义操作
- 执行效率低,时间开销大
- 主要用于大规模离线批处理
- 不适合迭代计算,交互式计算,实时流处理等场景
计算框架种类多,选型难
- 批处理:MapReduce
- 流处理:Storm,Flink
- 交互式计算:Impala,Presto
需要统一计算框架,简化技术选型
- 在一个统一的计算框架下,实现批处理,流处理,交互式计算
大规模分布式通用计算引擎
- Spark Core:核心计算框架
- Spark SQL:结构化数据查询
- Spark Streaming:实时流处理
具有高吞吐,低延时,通用易扩展,高容错等特点
采用Scala语言开发
提供多种运行模式
二、RDD 与编程模型
弹性分布式数据集,spark基于RDD进行计算
- 分布在集群中的只读对象集合
- 由多个partition组成
- 通过转换操作构造
- 失效后自动重构(弹性)
- 存储在内存或磁盘中
一个图例:SparkContext
弹性:每个阶段生成的RDD如果失效或者出错,不需要从源头文件重新计算,只需要从上一个RDD重新计算即可
RDD操作(operator)
Transformation(转换)
-将Scala集合或hadoop输入数据,构成一个新的RDD
-通过已有的RDD产生新的RDD
-惰性执行:只记录转换关系,不触发计算
- 常见的转换算子:map,filter,flatmap,union,distinct,sortbykey
Action(动作)
-通过RDD计算得到一个值或者一组值
-真正触发计算
-常见算子:first,count,collect,foreach,saveAsTextFile
RDD依赖
窄依赖(narrow dependency) 1:1
-父RDD中的分区最多只能被一个子RDD的一个分区使用
-子RDD如果有部分分区数据丢失或者损坏,只需要从对应的父RDD重新计算恢复
-如map,filter,union
宽依赖(shuffle/wide dependency)N:1
-子RDD分区依赖父RDD的所有分区
-子RDD如果部分或者全部分区数据丢失或损坏,必须从所有的父RDD分区重新计算
-相对于窄依赖,宽依赖付出的代价要高很多,数据恢复复杂,慢,尽量避免使用
-如groupByKey,reduceByKey,sortByKey
架构
- 主从架构,类似yarn可以做对比
- 主节点是Master,从节点是Worker(ResourceManager-NodeManager)
- 作业的管理进程是Driver(ApplcationMaster),负责申请资源,分发task,管理Executor
- 申请的资源是Executor(Container),一个Executor可以运行多个task(一个Container只运行一个task)
作业的提交模式
Local模式
- 单机运行,通常用于本地测试
- Spark程序以多线程方式直接运行在本地
Standalone模式
- Spark集群独立运行,不依赖第三方资源管理系统如YARN
- 采用Master-Slave架构
- Driver在Worker中运行,Master只负责管理集群
- Zookeeper负责Master HA,避免单点故障
- 适用于集群规模不大,数据量不大的情况
YARN模式
- YARN-Cluster模式:适用于生产环境
注意在yarn中,Executor实际是Container形式,Driver在ApplicationMaster中
- YARN-Client模式,适用于交互和调试,Driver在Client端
Spark作业的解析
- 逻辑查询计划,仅关注RDD的状态转换
- 物理查询计划,关注底层数据的状态,根据DAG图是否有宽窄依赖(或根据是否有shuffle),切分stage,
- 一般情况下,stage越多,shuffle越多,性能越低
监控页:4040端口,可以查看DAG图,stage的执行时间,shuffle read和write的执行时间