创建软链接,方便后期升级
ln -s /usr/spark/spark-2.4.0-bin-hadoop2.7 /usr/spark/spark
Spark 本地模式
Spark-shell
- Spark context Web UI available at http://master:4040
- 表示每个 Spark 应用运行时 WEB UI 监控界面,端口号为4040
- Spark context available as ‘sc’ (master = local[*], app id = local-1616911544992).
- 表示 SparkContext类实例名称为 sc
- 在运行 spark-shell 命令行的时候,创建 Spark 应用程序上下文实例对象 SparkContext
- 主要用于读取要处理的数据和调度程序执行
- Spark session available as ‘spark’.
- Spark2.x 的出现,封装 SparkContext 类,新的 Spark 应用程序的入口
- 表示的是 SparkSession 实例对象,名称为 Spark,读取数据和调度 Job 任务。
wordcount 程序案例
准备数据文件:wordcount.data,内容如下,上传HDFS目录【/datas/】
## 创建文件
vim wordcount.data
## 内容如下
spark spark hive hive spark hive
hadoop sprk spark
## 上传HDFS
hdfs dfs -put wordcount.data /datas/
编写代码进行词频统计:
## 读取HDFS文本数据,封装到RDD集合中,文本中每条数据就是集合中每条数据
val inputRDD = sc.textFile("/datas/wordcount.data")
## 将集合中每条数据按照分隔符分割,使用正则:https://www.runoob.com/regexp/regexp-syntax.html
val wordsRDD = inputRDD.flatMap(line => line.split("\\s+"))
## 转换为二元组,表示每个单词出现一次
val tuplesRDD = wordsRDD.map(word => (word, 1))
# 按照Key分组,对Value进行聚合操作, scala中二元组就是Java中Key/Value对
## reduceByKey:先分组,再聚合
val wordcountsRDD = tuplesRDD.reduceByKey((tmp, item) => tmp + item)
## 查看结果
wordcountsRDD.take(5)
## 保存结果数据到HDFs中
wordcountsRDD.saveAsTextFile("/datas/spark-wc")
## 查结果数据
hdfs dfs -text /datas/spark-wc/par*
截图如下:
监控页面
每个Spark Application应用运行时,启动WEB UI监控页面,默认端口号为4040,使用浏览器 打开页面,如下:
大多数现有的集群计算系统都是基于非循环的数据流模型。即从稳定的物理储存(如分布式文件系统)中加载记录,记录被传入由一组确定性操作构成的 DAG(Directed AcyclicGraph ,有向无环图),然后写回稳定储存。DAG 数据流图能够在运行时自动实现任务调度和故障恢复。
运行圆周率程序案例(本地模式)
Spark 框架自带的案例 Example 中涵盖圆周率 PI 计算程序,可以使用 【$SPARK_HOME/bin/spark-submit】提交应用执行,运行在本地模式。
而且 Spark 框架自带圆周率 jar 包
${SPARK_HOME}/bin/spark-submit --master local[2] --class org.apache.spark.examples.SparkPi ${SPARK_HOME}/examples/jars/spark-examples_2.11-2.4.5.jar 100
运行结果截图:
计算该圆周率的算法叫做 蒙特卡洛算法
在一个正方形当中,内切出一个圆形
然后 随机向正方形内均匀投 n 个点,其落入内切圆的内外点的概率满足如下
以上就是蒙特卡洛的大致理论,通过这个蒙特卡洛, 便可以通过迭代循环投点的方式实现蒙特 卡洛算法求圆周率。
Spark Standalone 集群模式
Standalone模式是 Spark 自带的一种集群模式,不同于前面本地模式启动多个进程来模拟集群环境,Standalone 模式是真实地在多个机器之间搭建 Spark 集群环境,完全可以利用该模式搭建多机器集群,用于实际的大数据处理。
Standalone 架构
Standalone集群使用了分布式计算中的master-slave模型,master是集群中含有Master进程的 节点,slave是集群中的Worker节点含有Executor进程。
架构图:
Spark Standalone集群,类似Hadoop YARN,管理集群资源和调度资源:
- 主节点 Master:
- 管理整个集群资源,接收提交应用,分配资源给每个应用,运行Task任务。
- 从节点 Workers:
- 管理每个机器的资源,分配对应的资源来运行Task。
- 每个从节点分配资源信息给Worker管理,资源信息包含内存Memory和CPU Cores核数 。
- 历史服务器 HistoryServer:
- Spark Application运行完成以后,保存事件日志数据至HDFS,启动HistoryServer可以查 看应用运行相关信息。
Standalone 集群模式部署
1.解压、环境变量
## 解压软件包
tar -zxvf /export/software/spark-2.4.5-bin-cdh5.16.2-2.11.tgz -C /export/server/
## 创建软连接,方便后期升级
ln -s /export/server/spark-2.4.5-bin-cdh5.16.2-2.11 /export/server/spark
## 进入配置目录
cd /export/server/spark/conf
## 修改配置文件名称
mv spark-env.sh.template spark-env.sh
vim spark-env.sh
## 添加内容如下:
JAVA_HOME=/usr/java/jdk1.8.0_171
SCALA_HOME=/usr/scala/scala-2.11.12
HADOOP_CONF_DIR=/usr/hadoop/hadoop-2.7.3/etc/Hadoop
2.Workers主机名称
将【$SPARK_HOME/conf/slaves.template】名称命名为【slaves】,填写从节点名称。
## 进入配置目录
cd /export/server/spark/conf
## 修改配置文件名称
mv slaves.template slaves
vim slaves
## 内容如下:
master
slave1
slave2
3.配置 Master、Workers、HistoryServer
在配置文件$SPARK_HOME/conf/spark-env.sh添加如下内容:
SPARK_MASTER_HOST=node1.itcast.cn
SPARK_MASTER_PORT=7077
SPARK_MASTER_WEBUI_PORT=8080
SPARK_WORKER_CORES=1
SPARK_WORKER_MEMORY=1g
SPARK_WORKER_PORT=7078
SPARK_WORKER_WEBUI_PORT=8081
SPARK_HISTORY_OPTS="-Dspark.history.fs.logDirectory=hdfs://master:9000/spark/eventLogs/ -Dspark.history.fs.cleaner.enabled=true"
4.创建 EventLogs存储目录
启动HDFS服务,创建应用运行事件日志目录,命令如下:
hadoop-daemon.sh start namenode
hadoop-daemons.sh start datanode
hdfs dfs -mkdir -p /spark/eventLogs/
5.配置 Spark 应用保存 EventLogs
将【$SPARK_HOME/conf/spark-defaults.conf.template】名称命名为【spark-defaults.conf】, 填写如下内容:
## 进入配置目录
cd /export/server/spark/conf
## 修改配置文件名称
mv spark-defaults.conf.template spark-defaults.conf
vim spark-defaults.conf
## 添加内容如下:
spark.eventLog.enabled true
spark.eventLog.dir hdfs://master:9000/spark/eventLogs/
spark.eventLog.compress true
6.设置日志级别
将【$SPARK_HOME/conf/log4j.properties.template】名称命名为【log4j.properties】,修改 级别为警告WARN。
## 进入目录
cd /export/server/spark/conf
## 修改日志属性配置文件名称
mv log4j.properties.template log4j.properties
## 改变日志级别
vim log4j.properties
修改内容如下:
7.分发到集群所有机器
提前在从节点中创建好目录,否则会报错。
然后在主节点上执行如下命令:
cd /export/server/
scp -r spark-2.4.5-bin-cdh5.16.2-2.11 [email protected]:$PWD
scp -r spark-2.4.5-bin-cdh5.16.2-2.11 root@ node3.itcast.cn:$PWD
## 远程连接到node2.itcast.cn和node3.itcast.cn机器,创建软连接
ln -s /export/server/spark-2.4.5-bin-cdh5.16.2-2.11 /export/server/spark
8.启动服务进程
在Master节点node1.itcast.cn上启动,进入$SPARK_HOME,必须配置主节点到所有从节点的 SSH无密钥登录,集群各个机器时间同步。
主节点 master 启动命令:
sbin/start-master.sh
从节点Workers启动命令:
sbin/start-slaves.sh
历史服务器HistoryServer:
sbin/start-history-server.sh
9.运行圆周率程序案例(集群模式)
${SPARK_HOME}/bin/spark-submit --master spark://master:7077 --class org.apache.spark.examples.SparkPi ${SPARK_HOME}/examples/jars/spark-examples_2.11-2.4.5.jar 100
10.Spark 应用架构
登录到 Spark HistoryServer 历史服务器 WEB UI 界面,点击刚刚运行圆周率 PI 程序:
查看运行状况:
切换到【Executors】Tab页面:
从图中可以看到Spark Application运行到集群上时,由两部分组成:Driver Program和Executors。
- Driver Program
- 相当于 AppMaster,整个应用管理者,负责应用中所有的 Job 的调度执行。
- 运行 JVM Process,运行程序的 MAIN 函数,必须创建 SparkContext 上下文对象。
- 一个 SparkApplication仅有一个。
- Executors
- 相当于一个线程池,运行 JVM Process,其中有很多线程,每个线程运行一个 Task 任务,一个 Task 运行需要 1 Core CPU,所有可以认为 Executor 中线程数就等于 CPU Core 核数。
- 一个 Spark Application 可以有多个,可以设置个数和资源信息。
Driver Program 是用户编写的数据处理逻辑,这个逻辑当中包含用户创建的 SparkContext。SparkContext 是用户逻辑与 Spark 集群主要的交互接口,他会和 Cluster Manager 交互,,包括向它 申请计算资源等。
Cluster Manager 负责集群的资源管理和调度,现在支持 Standalone、Apache Mesos 和 Hadoop的 YARN。Worker Node 是集群中可以执行计算任务的节点。 Executor 是在一 个 Worker Node 上为某应用启动的一个进程,该进程负责运行任务,并且负责将数据存在内存或者 磁盘上。Task 是被送到某个 Executor 上的计算单元,每个应用都有各自独立的 Executor,计算最 终在计算节点的 Executor 中执行。
用户程序从最开始的提交到最终的计算执行,需要经历以下几个阶段:
- 1.用户程序创建 SparkContext 时,新创建的 SparkContext 实例会连接到 ClusterManager。
- 2.Driver 会将用户程序划分为不同的执行阶段 Stage,每个执行阶段 Stage 由一组完全相同的 Task 组成,这些 Task 分别作用于待处理数据的不同分区。在阶段划分完成和 Task 创建后,Driver 会向 Executor 发送 Task。
- 3.Executor在接收到 Task 后,会下载 Task 的运行时依赖,在准备好 Task 的执行环境后,会开 始执行 Task,并且将 Task 的运行状态汇报给 Driver。
- 4.Driver 会根据收到的 Task 的运行状态来处理不同的状态更新。 Task 分为两种:一种是 Shuffle Map Task,它实现数据的重新洗牌,洗牌的结果保存到 Executor 所在节点的文件系统中;另 外一种是 Result Task,它负责生成结果数据。
- 5.Driver 会不断地调用 Task,将 Task 发送到 Executor 执行,在所有的 Task 都正确执行或者超过执行次数的限制仍然没有执行成功时停止。
11.WEB UI 监控
Spark 提供了多个监控界面,当运行 Spark 任务后可以直接在网页对各种信息进行监控查看。
运行 spark-shell 交互式命令在 Standalone 集群上,命令如下:
bin/spark-shell --master spark://node1.itcast.cn:7077
在spark-shell中执行词频统计WordCount 程序代码,运行如下:
val inputRDD = sc.textFile("/datas/wordcount.data")
val wordcountsRDD = inputRDD.flatMap(line => line.split("\\s+")).map(word => (word, 1)).reduceByKey((tmp, item) => tmp + item)
wordcountsRDD.take(5)
Standalone HA
Spark Standalone 集群是 Master-Slaves 架构的集群模式,和大部分的 Master-Slaves 结构集群一样,存在着 Master 单点故障(SPOF)的问题。
高可用 HA
为了解决这个单点故障的问题,Spark 提供了俩种方案:
- 基于文件系统的单点恢复(Single-Node Recovery with Local File System);
- 基于 Zookeeper 的 Standby Masters(Standby Masters with ZooKeeper);
Zookeeper 提供了一个 Leader Election 机制,利用这个机制可以保证虽然集群存在多个 Master,但是只有一个是 Active 的,其他的都是 Standby。当 Active 的 Master 出现故障的时候,另外的一个 Standby Master 会被选举出来。由于集群的信息,包括 Worker,Driver 和 Application 的信息都已经持久化到文件系统,因此在切换过程中只会影响新 Job 的提交,对于正在进行的 Job 没有任何的影响。加入 Zookeeper 的集群整体架构如下图所示:
基于 Zookeeper 实现 HA
1.停止 Standalone 集群
# 在 master 上执行命令
spark/sbin/stop-master.sh
spark/sbin/stop-slaves.sh
2.增加 Zookeeper 配置
对 Spark 配置文件 【$SPARK_HOME/conf/spark-env,sh】文件如下修改:
SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER
-Dspark.deploy.zookeeper.url=master:2181,slave1:2181,slave2:2181
-Dspark.deploy.zookeeper.dir=/spark-ha"
注释或删除MASTER_HOST内容:
# SPARK_MASTER_HOST=master
参数 | 含义 |
---|---|
spark.deploy.recoveryMode | 恢复模式 |
spark.deploy.zookeeper.url | ZooKeeper的Server地址 |
spark.deploy.zookeeper.dir | 保存集群元数据信息的文件、目录。包括Worker、Driver、Application信息。 |
注意:由于 Zookeeper 的选举机制,所以不能指定主机名。
3.分发 spark-env.sh
cd /export/server/spark/conf
scp -r spark-env.sh [email protected]:$PWD
scp -r spark-env.sh [email protected]:$PWD
4.启动服务器
先启动Zookeeper集群,再分别启动2个Master服务,最后启动Worker服务
启动 ZOOKEEPER 服务
zookeeper-daemons.sh start
在 master 和 slave1 分别启动Master服务
/export/server/spark/sbin/start-master.sh
查看哪个 Master 为 Active ,就在哪个Master机器上启动 Workers 服务
/export/server/spark/sbin/start-slaves.sh
默认情况下,谁先启动 Master 谁就为 Active Master,如下图。
5.运行圆周率程序案例(HA 测试)
Standalone HA集群运行应用时,指定ClusterManager参数属性为:
--master spark://master:port1,slave1:port2
提交圆周率PI运行集群,命令如下:
SPARK_HOME=/export/server/spark
${SPARK_HOME}/bin/spark-submit \
--master spark://master:7077:7077 \
--class org.apache.spark.examples.SparkPi \
${SPARK_HOME}/examples/jars/spark-examples_2.11-2.4.5.jar \
100
HA测试
在执行过程中,使用jps查看 Active Master 进程ID,将其kill,观察Master是否自动切换与应用运行完成结束。
我们在提交该案例之前查看主节点上的 Master 进程,然后新建会话,用 kill -9 9095 来杀死 Master 进程,这样就相当于主节点出问题,然后将任务交给另外一个节点,从而实现高可用。
结果如下图,master节点上出了问题,将任务都转移到了 slave1 节点上,测试成功!!!
再次开启 主节点进程后发现已经不再是 ALIVE状态。