1.什么是spark?
Spark 是一个用来实现快速而通用的集群计算的平台。
在速度方面,Spark 扩展了广泛使用的 MapReduce 计算模型,而且高效地支持更多计算模式,包括交互式查询和流处理。在处理大规模数据集时,速度是非常重要的。速度快就意味着我们可以进行交互式的数据操作,否则我们每次操作就需要等待数分钟甚至数小时。Spark 的一个主要特点就是能够在内存中进行计算,因而更快。不过即使是必须在磁盘上进行的复杂计算,Spark 依然比 MapReduce 更加高效。
总的来说,Spark 适用于各种各样原先需要多种不同的分布式平台的场景,包括批处理、迭代算法、交互式查询、流处理。通过在一个统一的框架下支持这些不同的计算,Spark使我们可以简单而低耗地把各种处理流程整合在一起。而这样的组合,在实际的数据分析过程中是很有意义的。不仅如此,Spark 的这种特性还大大减轻了原先需要对各种平台分别管理的负担。
Spark 所提供的接口非常丰富。除了提供基于 Python、Java、Scala 和 SQL 的简单易用的API 以及内建的丰富的程序库以外,Spark 还能和其他大数据工具密切配合使用。例如,Spark 可以运行在 Hadoop 集群上,访问包括 Cassandra 在内的任意 Hadoop 数据源。
2.spark 设计理念和基础架构
首先在说明spark 设计理念的之前我们先看看hadoop的架构,如下图:
那么hadoop 1.x 版本的缺点:
从Hdfs角度出发:
- 单点故障问题:因为NameNode含有我们用户存储文件的全部的元数据信息,当我们的NameNode无法在内存中加载全部元数据信息的时候,集群的寿命就到头了。
- 拓展性问题:NameNode在内存中存储了整个分布式文件系统中的元数据信息,并且NameNode只能有一台机器,无法拓展。单台机器的NameNode必然有到达极限的地方。
- 性能问题:当HDFS中存储大量的小文件时,会使NameNode的内存压力增加。
- 隔离性问题:单个namenode难以提供隔离性,即:某个用户提交的负载很大的job会减慢其他用户的job。
从MR 角度出发:
- 单点故障:依旧是单点故障问题,如果JobTracker挂掉了会导致MapReduce作业无法执行。
- 资源浪费:JobTracker完成了太多的任务,造成了过多的资源消耗,当map-reduce job非常多的时候,会造成很大的内存开销,潜在来说,也增加了JobTracker失效的风险,这也是业界普遍总结出老Hadoop的Map-Reduce只能支持4000节点主机的上限;
- 只支持简单的MapReduce编程模型:要使用Hadoop进行编程的话只能使用基础的MapReduce,而无法使用诸如Spark这些计算模型。并且它也不支持流式计算和实时计算。
针对hadoop1.x 出现的诸多缺陷,hadoop2.x 进行了大的版本升级,架构方面有了诸多调整如下图:
主要的改变有如下几点:
- 针对Hadoop1.0中NameNode制约HDFS的扩展性问题,提出HDFSFederation以及高可用HA。此时NameNode间相互独立,也就是说它们之间不需要相互协调。且多个NameNode分管不同的目录进而实现访问隔离和横向扩展,这样NameNode的可拓展性自然而然可用增加,据统计Hadoop2.0中最多可以达到10000个节点同时运行,并且这样的架构改进也解决了NameNode单点故障问题。再来说说高可用(HA),HA主要指的是可以同时启动2个NameNode。其中一个处于工作(Active)状态,另一个处于随时待命(Standby)状态。这样,当一个NameNode所在的服务器宕机时,可以在数据不丢失的情况下,手工或者自动切换到另一个NameNode提供服务
- 针对Hadoop1.0中MR的不足,引入了Yarn框架。Yarn框架中将JobTracker资源分配和作业控制分开,分为Resource Manager(RM)以及Application Master(AM)。 (关于yarn详细的介绍后面文件会有涉及,此处略过)
基于以上介绍,我们知道hadoop天然的优势就是在于解决高吞吐量,批量处理的业务场景,比如离线计算。离线数据仓库,如果需要实时性比较高,显然hadoop不符合这样的要求,从而就有了spark的出现,spark通过内存计算,极大地提高了数据处理的速度,比hadoop快几乎百倍,下面就让我们详细了解下spark
3.架构及生态:
- Spark Core:包含Spark的基本功能;尤其是定义RDD的API、操作以及这两者上的动作。其他Spark的库都是构建在RDD和Spark Core之上的。
- Spark SQL:提供通过Apache Hive的SQL变体Hive查询语言(HiveQL)与Spark进行交互的API。每个数据库表被当做一个RDD,Spark SQL查询被转换为Spark操作。
- Spark Streaming:对实时数据流进行处理和控制。Spark Streaming允许程序能够像普通RDD一样处理实时数据
- MLib:一个常用机器学习的算法库,算法被实现为对RDD的Spark操作。这个库包含可扩展的学习算法,比如分类、回归等需要对大量数据集进行迭代的操作
- GraphX:控制图、并行图操作和计算的一组算法和工具的集合。GraphX扩展了RDD API,包含控制图、创建子图、访问路径上所有顶点的操作
- Spark架构采用了分布式计算中的Master-Slave模型,Master是对应集群中的含有Master进程的节点,Slave是集群中含有Worker进程的节点。Master作为整个集群的控制器,负责整个集群的正常运行;Worker相当于是计算节点,接收主节点命令与进行状态汇报;Executor负责任务的执行;Client作为用户的客户端负责提交应用,Driver负责控制一个应用的执行,组成图如下:
Spark集群部署后,需要在主节点和从节点分别启动Master进程和Worker进程,对整个集群进行控制。在一个Spark应用的执行过程中,Driver和Worker是两个重要角色。Driver程序是应用逻辑执行的起点,负责作业的调度,即Task任务的分发,而多个Worker用来管理计算节点和创建Executor并行处理任务。在执行阶段,Driver会将Task和Task所依赖的file和jar序列化后传递给对应的Worker机器,同时Executor对相应数据分区的任务进行处理。
Spark的架构中的基本组件:
- Cluster Manager:在standalone模式中即为Master主节点,控制整个集群,监控worker。在YARN模式中为资源管理器
- Worker:从节点,负责控制计算节点,启动Executor或者Driver。在YARN模式中为NodeManager,负责计算节点的控制。
- Driver:运行Application的main()函数并创建SparkContext。
- Executor:执行器,在worker node上执行任务的组件、用于启动线程池运行任务。每个Application拥有独立的一组Executor。
- SparkContext:整个应用的上下文,控制应用的生命周期。
- RDD:Spark的基础计算单元,一组RDD可形成执行的有向无环图RDD Graph。
- DAG Scheduler:根据作业(task)构建基于Stage的DAG,并提交Stage给TaskScheduler。
- TaskScheduler:将任务(task)分发给Executor执行。
- SparkEnv:线程级别的上下文, 存储运行时的重要组件的引用。
4. spark 编程模型
spark 应用程序从编写到提交,执行,输出的整个过程入下图:
2.1 用户使用SparkContext提供的API编写Driver application (包括,spark sql spark streaming等相关的API)
2.2 使用SparkContent提交用户程序:利用BlockManager和BroadcastManager将任务的hadoop配置进行广播,然后由DAGScheduler将任务转换为RDD并组织成DAG,DAG还将划分为不同的Stage,最后由TaskScheduler借助ActerSystem将任务提交到集群管理器
2.3 集群管理器(Cluster Manager)给任务分配资源,将具体任务分配到Worker上,Worker创建Excuteror来运行任务
5. RDD计算模型
3.1 什么是RDD?
顾名思义,从字面理解RDD就是 Resillient Distributed Dataset,即弹性分布式数据集。它是Spark提供的核心抽象。RDD在抽象上来讲是一种抽象的分布式的数据集。它是被分区的,每个分区分布在集群中的不同的节点上。从而可以让数据进行并行的计算它主要特点就是弹性和容错性。弹性:RDD的数据默认情况下存放在内存中的,但是在内存资源不足时,Spark会自动将RDD数据写入磁盘容错性:RDD可以自动从节点失败中恢复过来。即如果某个节点上的RDD partition,因为节点故障,导致数据丢了,那么RDD会自动通过自己的数据来源重新计算该partition。RDD来源:通常是Hadoop的HDFS,Hive 表等等;也可以通过Linux的本地文件;应用程序中的数组;jdbc(mysql 等);也可以是kafka、flume数据采集工具、中间件等转化而来的RDD。入下图: