初识Spark
- Spark是一个通用的并行计算框架,由加州伯克利大学的AMP实验室开发于2009年,并于2010年开源.2013年在Apache旗下成长为大数据领域最活跃得开源框架之一,
- Spark也是基于map reduce算法模型实现的分布式计算框架.
Spark 针对MapReduce做了大量优化.
- 减少磁盘I/O Hadoop MapReduce的map端将中间输出和结果存储在磁盘中,reduce端又需要从磁盘中读取中间结果,导致磁盘IO成为性能瓶颈.Spark允许将map端的中间输出和结果存储到内存中,reduce端拉取中间结果时避免了大量的磁盘IO.Hadoop Yarn中的ApplicationMaster申请到Container后,具体任务需要利用NodeManager从HDFS的不同节点下载任务所需要的资源(如jar包),这也增加了磁盘的IO.Spark将应用程序上传的资源缓冲到Driver本地文件服务的内存中,当Executor执行任务时直接从Driver的内存中读取,也节省了大量的磁盘IO.
- 增加并行度 由于将中间结果写到磁盘与从磁盘读取中间结果属于不同的环节,Hadoop将他们简单的通过串行执行衔接起来.Spark把不同的环节抽象为Stage,允许多个Stage既可以串行执行,又可以并行执行.
- 避免重新计算 当Stage中某个分区的Task执行失败后,会重新对此Stage调度,但是重新调度的时候会过滤已经执行成功的分区任务,所以不会造成重新计算和资源浪费.
- 可选的Shuffle排序 Hadoop MapReduce在Shuffle之前有着固定的排序操作,而Spark则可以根据不同的场景选择在map端排序还是在reduce端排序.
- 灵活的内存管理策略 Spark将内存分为堆上的存储内存,堆外的存储内存,堆上的执行内存,堆外的执行内存.又提供了执行内存和存储内存之间的"软"边界实现.Spark默认使用"软"边界的实现,执行内存或者存储内存中任意一方在资源不足时都可以借用另一方的内存,最大限度的提高了内存的利用率,减少对资源的浪费.Spark由于对内存使用的偏好,内存资源的多寡和使用率就显得尤为重要.对此Spark的内存管理器提供的Tungsten实现了一种与操作系统内存Page非常相似的数据结构,由于直接操作操作系统内存,节省了创建Java对象在堆内占用的内存,使得Spark对内存的使用率更加接近硬件.Spark会给每个Task分配一个配套的内存管理器,对Task粒度的内存进行管理.Task的内存可以被多个内部的消费者消费,任务内存管理器对每个消费者进行Task内存的分配和管理,因此Spark内存有着更细粒度的管理.
Spark的一些其他特点:
- 检查点支持 Spark的RDD之间维护了Lineage关系,一旦某个RDD失败,则可以由父RDD重建,虽然lineage可以用于错误后RDD的恢复,但对于很长的Lineage来说,恢复过程非常的耗时,如果应用启动了检查点,那么在Stage中的Task都执行成功后,SparkContext将把RDD计算的结果保存到检查点,这样当某个RDD执行失败后,再由父RDD重建时就不需要重新计算,而是直接从检查点恢复数据.
- 易于使用 Spark现在支持Java,Scala,Python和R等语言编写应用程序,大大降低了使用者的门槛.除此之外,还自带80多个高等操作符,允许在Scala,Python,R的shell中进行交互查询.
- 支持交互式查询 Spark使用Scala开发,并借助Scala类库中的Lloop实现交互式shell,提供对REPL(Read-eval-print-loop)的实现.
- 支持流式计算 与Hadoop 的 MapReduce只能处理离线数据相比,Spark还支持实时的流式计算.Spark依赖Spark Streaming对数据进行实时的处理,其流式处理能力还要强于Storm.
- 高可用性 Spark自身实现了Standalone部署模式,此模式下的Master可以有多个,解决了单点故障问题.Spark也完全支持使用外部部署模式,比如常用的Yarn,以及Mesos,EC2等.
- 丰富的数据源支持 Spark除了可以访问操作系统自身的文件系统和HDFS之外,还可以访问Kafka,Socket,HBase,Hive以及任何Hadoop的数据源,这极大的方便了已经使用HDFS,HBase的用户顺利迁移到Spark.
- 丰富的文件格式支持 Spark支持文件文件格式,CSV文件格式,JSON文件格式,ORC文件格式,Parquet文件格式,Libsvm文件格式,也有利于Spark与其他数据处理平台对接.
Spark的使用场景
- 医疗健康
- 电商
- 安全领域
- 金融领域 构建金融云,量化投资
Spark的基本概念
- RDD(resillient distributed dataset):弹性分布式数据集.Spark应用程序通过使用Spark的转换API,可以将RDD封装为一系列具有血缘关系的RDD,也就是DAG(有向无环图),只有通过Spark的动作API才会将RDD及其DAG提交到DAGScheduler.RDD的祖先一定是一个跟数据源相关的RDD,负责从数据源迭代读取数据.
- DAG(Directed Acycle graph):有向无环图,在图论中,如果有一个有向图无法从某一个丁点出发经过若干条边回到该点,则这个图是一个有向无环图.Spark使用DAG来反应RDD之间的依赖或者血缘关系.
- Partition:数据分区,即一个RDD的数据可以划分为多个分区,Spark根据Partition的数量来确定Task的数量.
- NarrowDependency:窄依赖,即子RDD依赖于父RDD中固定的Partition,NarrowDependency分为OneToOneDependency和RangeDependency两种.
- ShuffleDependency:Shuffle依赖.子RDD对父RDD各个Partition的依赖将取决于分区计算器的算法.
- Job:用户提交的作业.当RDD及其DAG被提交给DAGScheduler调度后,DAGScheduler会将所有RDD中的转换及动作视为一个Job,一个Job由一到多个Task组成.
- Stage:Job的执行阶段.DAGScheduler按照ShuffleDependency作为Stage的划分节点对RDD的DAG进行Stage划分(上游的Stage将作为ShuffleMapStage).因此一个Job可能被划分为一到多个Stage.Stage分为ShuffleMapStage和ResultStage两种.
- Task:具体执行任务.一个Job在每个Stage内都会按照RDD的Partition数量,创建多个Task.Task分为ShuffleMapTask和ResultTask两种.ShuffleMapStage中的Task为ShuffleMapTask,而ResultStage中的Task为ResultTask.ShuffleMapTask和ResultTask类似Hadoop中的Map任务和Result任务.
- Shuffle:Shuffle是所有MapReduce计算框架的核心执行阶段,Shuffle用于打通map任务(在Spark中就是ShuffleMapTask)的输出与reduce任务(在Spark中就是ResultTask)的输入,map任务的中间输出结果按照指定的分区策略(比如:按照key值hash)分配给处理某一分区的reduce任务.