Spark概述
Spark效率高、运行速度快的原因:
- 内存计算(将数据加载到内存中计算)
- DAG有向无环图设计机制(可以对数据的处理进行优化,使得数据处理像流水线般作业,效率高)
Spark使用简单:
- 支持Scala、Python、Java、R等语言
Spark的通用性:
- 具备完整的解决方案:
- Sql查询:Spark SQL
- 流式计算:Spark Streaming
- 机器学习:Spark MLlib
- 图数据计算:Spark GraphX
Spark运行模式多样化:
- 单机版本
- 独立的集群模式(本地集群或云端集群)
- 可访问加载多个数据源(HDFS、Hive、HBase等等)
Spark生态系统
数据处理类型:
- 复杂的批数据处理:要求十分钟到数小时
- 基于历史数据的交互式查询:要求数十秒到数分钟
- 基于实时性数据流的数据处理:要求数百毫秒到数秒
对于上述的三种场景,Spark的生态系统基本都可以满足,
具体来说:
应用场景 | 时间跨度 | 其他框架 | Spark相应组件 |
---|---|---|---|
批数据处理 | 小时级 | MapReduce 或 Hive | Spark Core |
基于历史数据的交互式查询 | 分钟级 或 秒级 | Impala | Spark Sql |
基于实时数据的流处理 | 毫秒 或 秒级 | Storm | Spark streaming 或 Structured Streaming |
基于历史数据的数据挖掘 | - | Mahout | MLlib |
图数据的处理 | - | Hama | GraphX |
Spark基本概念
RDD(Resilient Distributed Dataset 弹性分布式数据集)
在Spark中,所有的数据都会被转化为RDD上的transformations(转换)和actions(动作),进行数据的处理和计算,RDD可以看做是一个被 划分到不同节点(块) 上进行并行处理的数据集合,也可以将RDD放入内存中,进行一系列的计算和转化(例如,机器学习中常见的需要反复迭代的任务,此时速度和效率将会很快)
RDD中的数据被分区保存时,是存在重复的保存的,即元素可以被分别保存到不同分区,防止某一台机器挂掉,使得数据丢失
DAG(有向无环图)
DAG反映了RDD之间的依赖关系,即将RDD之间的 transformations(转换) 和 actions(动作) 操作连接成一个有向无环图,使得RDD之间的操作像流水线般无缝连接。
Executor
是运行在 工作节点(WorkerNode) 的一个进程, 负责运行具体任务Task,即每个工作节点运行一个Executor进程,该进程再运行多个线程去执行具体的操作。
Application:
就是用户编写的Spark应用程序
Task
运行在Executor上的工作单元
Job
一个Job包含多个RDD及作用于相应RDD上的各种操作
Stage
是Job的基本调度单位,一个Job会分为多组Task,每组Task被称为Stage或TaskSet,代表了一组关联的、相互之间没有shuffle依赖的任务组成的任务集
Spark基本架构
- Driver Program:主节点(一个),任务控制的节点
- Cluster Manager:集群整体资源的调度和分配
- Work Node:工作节点(多个)
- 每个Work Node都有一个Executor(进程),Executor再派生出多个线程去执行具体的Task
- 再将每个Task汇总到工作节点
具体就是:
任务控制节点(Driver)向Cluster Manager申请资源,启动一个Executor,再根据具体的任务(Task百代码)去执行。
执行完后结果,返回给Driver控制节点
或者写入HDFS或其他数据库:
Spark基本运行流程
下图是Spark的基本运行流程
环境
如果把Spark的运行比喻为一场战争的话,那么首先我们应该建立一个指挥所,那么SparkContext就是指挥所,负责整个任务的调度、监控、执行、结果的汇总等等
创建好SparkContext之后,需要去申请资源
然后,资源管理器就会去分配资源,启动Executor进程:
此时,Work Node上的进程就会派生出多个线程去执行任务,任务是怎么来的呢???
任务??
刚才的那个指挥官SparkContext会根据具体的代码,生成一个DAG任务的有向无环图:
然后DAG有向无环图,会经过DAG Scheduler这个组件,就DAG有向无环图分解为Stage(阶段)
而每个Stage(阶段),都包含了很多具体的任务
那么这么多的任务,具体由那个机器去处理呢?上面提到我们的环境,即每个Work Node已经建立好了,现在具体的任务也有了,那么这里就设计到任务的分发问题,每个Work Node都会向Task Scheduler这个组件去申请任务,Task Schedule具体要怎么分配任务给Work Node呢?
具体的分发依据是:计算向数据靠拢,就是尽量的减少数据的移动开销,优先把任务分发给数据所在的节点上,例如机器A 和 机器B同时向Task Schedule申请任务,而此时数据在机器A中,那么就将任务分发给机器A,实现数据的本地化操作,若是将任务给了机器B,那么数据同时也要由A传输到B,效率太低。