spark
spark简介
Apache Spark是一个围绕速度、易用性和复杂分析构建的大数据处理框架,最初在2009年由加州大学伯克利分校的AMPLab开发,并于2010年成为Apache的开源项目之一,与Hadoop和Storm等其他大数据和MapReduce技术相比,Spark有如下优势:
- Spark提供了一个全面、统一的框架用于管理各种有着不同性质(文本数据、图表数据等)的数据集和数据源(批量数据或实时的流数据)的大数据处理的需求
- 官方资料介绍Spark可以将Hadoop集群中的应用在内存中的运行速度提升100倍,甚至能够将应用在磁盘上的运行速度提升10倍
架构及生态
通常当需要处理的数据量超过了单机尺度(比如我们的计算机有4GB的内存,而我们需要处理100GB以上的数据)这时我们可以选择spark集群进行计算,有时我们可能需要处理的数据量并不大,但是计算很复杂,需要大量的时间,这时我们也可以选择利用spark集群强大的计算资源,并行化地计算,其架构示意图如下:

- 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一样处理实时数据
- MLlib:一个常用机器学习算法库,算法被实现为对RDD的Spark操作。这个库包含可扩展的学习算法,比如分类、回归等需要对大量数据集进行迭代的操作。
- GraphX:控制图、并行图操作和计算的一组算法和工具的集合。GraphX扩展了RDD API,包含控制图、创建子图、访问路径上所有顶点的操作
Spark与hadoop比较
- Hadoop有两个核心模块,分布式存储模块HDFS和分布式计算模块Mapreduce
- spark本身并没有提供分布式文件系统,因此spark的分析大多依赖于Hadoop的分布式文件系统HDFS
- Hadoop的Mapreduce与spark都可以进行数据计算,而相比于Mapreduce,spark的速度更快并且提供的功能更加丰富
- 关系图如下:

spark运行流程及特点:

- 构建Spark Application的运行环境,启动SparkContext
- SparkContext向资源管理器(可以是Standalone,Mesos,Yarn)申请运行Executor资源,并启动StandaloneExecutorbackend,
- Executor向SparkContext申请Task
- SparkContext将应用程序分发给Executor
- SparkContext构建成DAG图,将DAG图分解成Stage、将Taskset发送给Task Scheduler,最后由Task Scheduler将Task发送给Executor运行
- Task在Executor上运行,运行完释放所有资源
Spark运行特点
- 每个Application获取专属的executor进程,该进程在Application期间一直驻留,并以多线程方式运行Task。这种Application隔离机制是有优势的,无论是从调度角度看(每个Driver调度他自己的任务),还是从运行角度看(来自不同Application的Task运行在不同JVM中),当然这样意味着Spark Application不能跨应用程序共享数据,除非将数据写入外部存储系统
- Spark与资源管理器无关,只要能够获取executor进程,并能保持相互通信就可以了
- 提交SparkContext的Client应该靠近Worker节点(运行Executor的节点),最好是在同一个Rack里,因为Spark Application运行过程中SparkContext和Executor之间有大量的信息交换
- Task采用了数据本地性和推测执行的优化机制
spark集群运行模式
- Standalone模式使用Spark自带的资源调度框架
- 采用Master/Slaves的典型架构,选用ZooKeeper来实现Master的HA
- 框架结构图如下:

- 该模式主要的节点有Client节点、Master节点和Worker节点。其中Driver既可以运行在Master节点上中,也可以运行在本地Client端。当用spark-shell交互式工具提交Spark的Job时,Driver在Master节点上运行;当使用spark-submit工具提交Job或者在Eclips、IDEA等开发平台上使用”new SparkConf.setManager(“spark://master:7077”)”方式运行Spark任务时,Driver是运行在本地Client端上的
- 运行过程如下图:(参考至:http://blog.csdn.net/gamer_gyt/article/details/51833681)

- SparkContext连接到Master,向Master注册并申请资源(CPU Core 和Memory)
- Master根据SparkContext的资源申请要求和Worker心跳周期内报告的信息决定在哪个Worker上分配资源,然后在该Worker上获取资源,然后启动StandaloneExecutorBackend;
- StandaloneExecutorBackend向SparkContext注册;
- SparkContext将Applicaiton代码发送给StandaloneExecutorBackend;并且SparkContext解析Applicaiton代码,构建DAG图,并提交给DAG Scheduler分解成Stage(当碰到Action操作时,就会催生Job;每个Job中含有1个或多个Stage,Stage一般在获取外部数据和shuffle之前产生),然后以Stage(或者称为TaskSet)提交给Task Scheduler,Task Scheduler负责将Task分配到相应的Worker,最后提交给StandaloneExecutorBackend执行;
- StandaloneExecutorBackend会建立Executor线程池,开始执行Task,并向SparkContext报告,直至Task完成
- 所有Task完成后,SparkContext向Master注销,释放资源
spark集群部署
spark简单集群部署
配置环境如下:
| master(alive) | work | work | work |
| 192.168.1.100 (s100) | 192.168.1.101 (s101) | 192.168.1.102 (s102) | 192.168.1.103 (s103) |
集群架构中已经部署完jdk和hadoop,现在首先在master节点部署spark
root@s100:~# tar xf /spark-1.6.3-bin-hadoop2.3.tgz -C /soft/ root@s100:/soft# ln -s /soft/spark-1.6.3-bin-hadoop2.3 /soft/spark root@s100:/soft/spark/conf# cp spark-env.sh.template spark-env.sh #在spark-env.sh配置文件中最后添加如下参数即可 root@s100:/soft/spark/conf# vim spark-env.sh export JAVA_HOME=/soft/jdk export SPARK_MASTER_IP=s100 export SPARK_MASTER_PORT=7077 #配置slaves文件,指定work的节点,在此配置文件最后添加如下参数即可 root@s100:/soft/spark/conf# cp slaves.template slaves s101 s102 s103
配置spark的环境变量
root@s100:/soft# vim /etc/environment JAVA_HOME=/soft/jdk HADOOP_HOME=/soft/hadoop ZOOKEEPER_HOME=/soft/zk HIVE_HOME=/soft/hive FLUME_HOME=/soft/flume HBASE_HOME=/soft/hbase STORM_HOME=/soft/storm KAFKA_HOME=/soft/kafka SPARK_HOME=/soft/spark PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/so ft/jdk/bin:/soft/hadoop/bin:/soft/hadoop/sbin:/soft/zk/bin:/soft/hive/bin:/soft/f lume/bin:/soft/hbase/bin:/soft/storm/bin:/soft/kafka/bin:/soft/spark/bin:/soft/sp ark/sbin" root@s100:~# source /etc/environment
将s100节点的spark分发到其他work节点上
root@s100:/soft# rsync -rl spark spark-1.6.3-bin-hadoop2.3 s101:/soft/ root@s100:/soft# rsync -rl spark spark-1.6.3-bin-hadoop2.3 s102:/soft/ root@s100:/soft# rsync -rl spark spark-1.6.3-bin-hadoop2.3 s103:/soft/
启动分布式spark
root@s100:/soft# /soft/spark/sbin/start-all.sh #查看各个节点的spark启动后的进程 root@s100:/soft# jps 4833 ResourceManager 20977 Master 21025 Jps 4535 NameNode root@s101:~# jps 19073 QuorumPeerMain 4403 NodeManager 29079 Jps 20014 Worker 4111 DataNode root@s102:~# jps 17936 QuorumPeerMain 26978 Jps 4034 DataNode 4326 NodeManager 18871 Worker root@s103:~# jps 19441 Jps 4019 DataNode 4311 NodeManager 18445 QuorumPeerMain 19389 Worker
启动spark的web界面,使用http://192.168.1.100:8080访问即可

部署spark高可靠
集群安装完毕,但是有一个很大的问题,那就是Master节点存在单点故障,要解决此问题,就要借助zookeeper,并且启动至少两个Master节点来实现高可靠
| master(alive) | work & zk | work & zk | work & zk | master(standby) |
| 192.168.1.100 (s100) | 192.168.1.101 (s101) | 192.168.1.102 (s102) | 192.168.1.103 (s103) | 192.168.1.104 (s104) |
这里将上面的集群完善下来实现spark集群的高可用,首先将spark程序分发到s104(准备作为备用的master),并且保证s101,s102,s103节点上已经部署zookeeper并启动
root@s100:/soft# rsync -rl spark spark-1.6.3-bin-hadoop2.3 s104:/soft/
要实现高可用,就要修改spark的配置文件spark-env.sh,配置如下:
#停止集群中spark进程 root@s100:~# /soft/spark/sbin/stop-all.sh root@s100:/soft/spark/conf# vim spark-env.sh export JAVA_HOME=/soft/jdk #这里需要注释掉master,对于哪个节点会成为master,由选举产生 #export SPARK_MASTER_IP=s100 export SPARK_MASTER_PORT=7077 export SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.depl oy.zookeeper.url=s101,s102,s103 -Dspark.deploy.zookeeper.dir=/root/spark/zk" #将修改好的配置文件分发到各个节点上 root@s100:/soft/spark/conf# scp spark-env.sh s101:/soft/spark/conf/ root@s100:/soft/spark/conf# scp spark-env.sh s102:/soft/spark/conf/ root@s100:/soft/spark/conf# scp spark-env.sh s103:/soft/spark/conf/ root@s100:/soft/spark/conf# scp spark-env.sh s104:/soft/spark/conf/ #重新启动集群spark进程 root@s100:~# /soft/spark/sbin/start-all.sh
在s104节点上启动spark master进程
root@s104:~# /soft/spark/sbin/start-master.sh root@s104:~# jps 13266 Master
这样spark集群的高可靠就搭建完成了,当s100节点的spark master宕机了,s104作为备用的master就会成为真正的master来管理其他work节点
spark计算实例
提交一个spark-submit的task
root@s100:~# spark-submit --class org.apache.spark.examples.SparkPi --master spark://s100:7077 --executor-memory 200M --total-executor-cores 2 /soft/spark/lib/spark-examples-1.6.3-hadoop2.3.0.jar 100
提交一个spark-shell的task,来运行wordcount
root@s100:~# cat helloworld.txt
hello world
hello goser
hello zhangsan
hello lisi
#上传文件到hadoop
root@s100:~# hadoop fs -mkdir /wc
root@s100:~# hadoop fs -put helloworld.txt /wc/1.log
root@s100:~# hadoop fs -put helloworld.txt /wc/2.log
root@s100:~# spark-shell --master spark://s100:7077 --executor-memory 512M --total-executor-cores 3
#将计算的结果保存到hadoop上,不过计算的结果会被分片
scala> sc.textFile("hdfs://s100:8020/wc").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).sortBy(_._2,false).saveAsTextFile("hdfs://s100:8020/out4")
#如果让计算的结果不分片,将reduceByKey参数设置为1,表示只有一个分片
scala> sc.textFile("hdfs://s100:8020/wc").flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_,1).sortBy(_._2,false).saveAsTextFile("hdfs://s100:8020/out5")
浙公网安备 33010602011771号