分布式计算平台Spark:基础入门
文章目录
20201216
一、课程
-
大数据组件
-
分布式存储
-
Zookeeper:利用分布式存储系统实现小的核心数据的存储(加紧复习)
-
抓紧复习
-
HDFS:离线大数据文件系统数据存储(加紧复习)
-
抓紧复习
- 为了解决大数据存储问题:分布式磁盘
-
Hive:离线数据仓库【表】
- 为了解决统一化和规范化数据管理问题
-
Redis:实时内存式NOSQL数据库【所有数据都在内存中】
- 为了解决数据高并发和高性能读写问题
-
HBASE:实时基于分布式内存的NoSQL数据库【内存+HDFS】(加紧复习)
-
抓紧复习
-
基于性能和大数据量之间做了一个平衡
-
解决性能与存储之间的瓶颈的思想:冷热数据的分离
-
冷数据:不经常被使用的数据
-
热数据:经常被使用的数:最新的数据
-
先产生的比较早的数据写入HDFS
-
怎么保证读HDFS也能很快?
-
构建数据存储的有序
-
读缓存:BlockCache
blockcache这个怎么实现的
-
列族:存储:Store 如果不划分列族的情况下所有的列都存储在一个store
-
设计列族的主要目的就是减少比较次数
-
-
-
数据被使用的概率随着时间的流逝而逐渐降低
-
-
二级索引:走两次索引,代替全表扫表
- Phoenix
- ES
-
-
Kafka:分布式实时消息队列【传递数据】(加紧复习)
- 为了解决高可靠的实时场景下的数据实时缓存问题
- 实时:磁盘文件、-》顺序写、pagecache:页缓存机制、zero copy
- 核心:数据一次性语义
- 有且仅处理一次,不重复,不丢失
-
ES:分布式全文检索搜索引擎
- 构建全文索引
-
-
分布式计算
- 处理数据步骤:三步
- step1:读取数据
- 变量:Seq
- step2:处理数据
- 函数:map/filter/flatMap/zipwithindex/reduce/fold/group
- step3:保存结果
- step1:读取数据
- MapReduce:离线批处理的分布式计算
- Input:负责输入:InputFormat
- TextInputFormat:文件
- DBInputFormat:数据库
- TableInputFormat:读HBASE
- Map:MapTask处理每一个分片的数据
- Shuffle:排序、分区、分组
- Reduce:ReduceTask处理所有的数据
- Output:负责输出
- Input:负责输入:InputFormat
- Spark
- Flink
- 处理数据步骤:三步
-
数据采集
- Flume
- Sqoop
- Logstash
- FileBeat
-
其他辅助性组件
- Zookeeper:解决分布式存在的问题
- 存储核心元数据信息:HBASE、Kafka
- 解决HA问题
- Hue:可视化操作平台
- Oozie:分布式的调度平台
- CM:集群管理平台
- Zookeeper:解决分布式存在的问题
-
二、目标
-
Spark的介绍
- 什么是Spark?
- Spark能实现什么功能?
- 类似的工具,为什么选择Spark?
- 基本的Spark的特点
-
Spark环境部署
-
架构
-
集群搭建
-
基本使用方式
-
三、Spark的起源与发展
1、分布式计算发展
-
分布式计算发展
- HPC:高性能计算
- 云计算平台:虚拟机
- 阿里云
- 华为云
- 亚马逊云
- 大数据
- 分布式存储
- 分布式计算
-
分布式计算平台的演变
-
第一代:MapReduce
- 设计:为了让廉价机器也能实现分布式处理
-
第二代:Tez
-
第三代:Spark
- 设计:基于内存式的灵活性的编程计算框架
- 以离线批处理为主
-
第四代:Flink
- 设计:流式高性能计算
-
-
以实时数据流计算为主
为什么基于内存式的还没有流式的有优势?:见spark学习笔记中问题部分。
2、Spark诞生与发展
- 诞生
- 问题:最早使用MapReduce等工具实现分布式计算,出现了两个问题
- MapReduce的计算过程非常慢,导致性能很差
- Mapreduce编程非常死板(5大阶段不可调),不灵活
- 解决:需要设计一些新的工具
- databricks:研发一个新的工具,结合目前市场上很多分布式工具的特点,融合以后构建Spark
- 问题:最早使用MapReduce等工具实现分布式计算,出现了两个问题
- 发展
-
官网
- spark.apache.org
- databricks.com
-
介绍
Apache Spark is a lightning-fast unified analytics engine for big data and machine learning. It was originally developed at UC Berkeley in 2009.
- lightning-fast:光速
- 快
- unified analytics engine:统一化的分析引擎
- 功能非常强大
- 分析的类型
- 离线代码开发
- 交互式分析
- 实时计算分析
- Python
- R
- 机器学习
- machine learning:机器学习
- lightning-fast:光速
-
定义:是一个分布式的统一化的计算框架;类似于前面学的MapReduce+yarn
3、Spark功能与特点
-
官方对Spark的一个介绍
At a high level, every Spark application consists of a driver program #每个Spark程序都会包含一个驱动程序:Driver that runs the user’s main function #这个driver运行在用户的main方法中 and executes various parallel operations on a cluster. #并且在集群中执行各种并行化操作 The main abstraction Spark provides is a resilient distributed dataset (RDD), #Spark中提供了一个主要的抽象:RDD【弹性分布式数据集】【SparkCore中的核心数据结构】 which is a collection of elements partitioned across the nodes of the cluster # 被分区存储在各个节点中的一个元素的集合【类似于MapReduce中的分片的存在,所有分片构建一个RDD】 that can be operated on in parallel. #可以被并行化的操作 RDDs are created by starting with a file in the Hadoop file system (or any other Hadoop-supported file system), #RDD可以被创建从一个Hadoop文件系统中被创建 or an existing Scala collection in the driver program, and transforming it. #或者从一个Scala的集合中进行创建,由driver来实现,并且对RDD进行转换 Users may also ask Spark to persist an RDD in memory, #用户可以将RDD中的数据持久化【缓存】在内存中, 【scala中结果会存在新生成的集合中这个集合可能会被回收:后边文档已有解决方案】 allowing it to be reused efficiently across parallel operations. #方便多次使用 Finally, RDDs automatically recover from node failures. #最终,RDD会自动的从失败中恢复
-
RDD
-
数据处理的流程
- Input:读数据源,将数据源的数据封装到一个变量中
- Transform:对这个变量的数据进行转换处理,得到结果
- Output:将结果保存即可
-
MapReduce
-
需求:1 + …… + 9
-
Input
-
功能一:将数据进行分片,得到每个split
- 目的:每个Task要处理一部分数据,先将数据划分
- 举例:将1到9,分成若干个部分,分成3个部分
- split1:1,2,3
- split2:4,5,6
- split3:7,8,9
-
功能二:将每个分片的每条数据转换为KV结构
-
目的:整个MapReduce中所有的数据都以KV结构进行存储和处理
-
split1
(a,1) (a,2) (a,3)
-
split2
(a,4) (a,5) (a,6)
-
split3
(a,7) (a,8) (a,9)
-
-
-
-
Tranform
- Map:每个Split启动MapTask进程进行处理,map方法
- MapTask1:(a,6)
- MapTask2:(a,15)
- MapTask3:(a,24)
- Reduce:启动一个ReduceTask来对所有Map的结果进行处理
- ReduceTask:(a,45)
- Map:每个Split启动MapTask进程进行处理,map方法
-
Output
-
问题
- MapReduce中的KV在很多场景下是不方便的
- 只要存储一个值
- 需要存储多个值
- MapReduce中的KV在很多场景下是不方便的
-
-
-
SparkCore
-
Input:读取数据
-
RDD:将读取到的所有数据放入RDD中
-
问题:数据怎么划分?
- RDD中的数据会被分区存储在不同的节点中
- RDD的每个分区【partition】 = MapReduce中的每个分片【split】
-
问题:RDD中存储的数据格式是什么样的?
- RDD【T】
- RDD[String]
- RDD[(String,Int)]
- RDD【T】
-
理解:RDD类似于scala中的集合,但是RDD是分布式的,RDD集合中的数据分区存储在不同的机器上
疑问这个rdd会随分区个数的变化重新将存储的数据分配到不同的节点上吗;会重新分配
-
-
-
TransForm:对RDD中的数据进行转换处理
- RDD中很多的函数与Scala集合的函数是一致的
-
Output
-
-
-
Speed
-
快
-
流程设计:读取、处理、保存
-
保证整个流程中提高性能:积极的将数据存储在内存中
-
问题:内存中的数据是不稳定的,空间较小
-
解决
-
如果内存不足以存放所有数据,将部分数据持久化persist在磁盘中 disk
-
如果内存数据丢失,通过特殊的机制来保证数据可恢复或者可用
-
-
-
Ease of Use
- 好使
- 支持的开发接口比较多
- Java
- Scala
- SQL
- Python
- R
-
Generality
-
功能非常全面
-
SparkCore:Spark中最核心的组件
- 类似于MapReduce,替代了MapReduce
- 用于实现离线的批处理,可以使用Java、Scala进行开发代码
-
SparkSQL :Spark中用于实现SQL处理的组件(源自于hive)
- 类似于Hive,用于替代Hive实现SQL计算
- 支持SQL语句对数据仓库中的数据或者表的数据进行处理
-
SparkStreaming:准实时计算
- 类似于Storm,用于实现实时计算
- 准实时:用微小为单位的批处理来模拟实时计算
- 例如:每200ms处理一次
- 真实时:Storm、Flink!!!
- 以数据为单位进行计算,产生一条数据,处理一条数据
-
SparkStructStreaming:结构化流
- SQL + Streaming
-
Spark MLlib:机器学习的算法库
- 工作中用算法库来实现算法模型的构建
- 推荐模型的算法
-
Spark Graphx:图计算
- 数据结构的图
-
-
Runs Everywhere
-
Spark支持各种数据源(内部已将封装了这些api)
-
流程:读取、处理、保存
-
数据源:读取、保存
-
常用的数据源
- SparkCore:HDFS、HBASE
- SparkSQL:Hive、结构化数据【MySQL、Json、文件、Parquet(列式存储)】
- SparkStreaming(流式数据):Kafka、HBASE、Redis
-
-
运行在各种分布式资源平台中
-
http://spark.apache.org/docs/2.4.5/
-
资源平台
-
Standalone
- Spark自带的集群资源管理平台
-
Messos
- 类似于YARN,国内应用的不多
-
YARN
- 将Spark的程序放在YARN运行,由YARN做资源管理
-
Kubernetes
- 新一代的分布式资源容器,类似于Docker
-
-
4、应用场景
- 功能:用于实现各种场景下的分布式计算
- 应用场景
- 数据仓库:SparkCore实现ETL(解密、过滤等操作)
- 数据分析
- SparkSQL来实现数据离线分析
- SparkStreaming或者StructStreaming来实现实时数据分析(flink取代的是这部分)
- 推荐系统
- Spark MLlib
- 特点
- 快
- 好使
- 通用性
- 支持多数据源和多平台
四、Spark环境部署测试
1、版本与编译
-
版本
- 1.x:早期的大数据平台所使用的版本,功能性能都有一些缺陷
- 2.x:目前企业中应用最多的版本
- 2.4.5
- 3.x:最新的版本,增加了很多新的特性,用来提高性能
- 目前暂时没有对应的应用环境
-
发行厂商
- Apache:http://archive.apache.org/dist/spark/spark-2.4.5/
- CDH
- 为什么不用Apache,而选用Cloudera公司的产品
- 基于稳定性的考虑
- Cloudera所提供的Spark版本是有缺陷的
- Spark的编译好的包中是没有SparkSQL的
- Cloudera公司自己有Impala
- 为什么不用Apache,而选用Cloudera公司的产品
-
基于以上的问题,需要基于Cloudera公司的依赖,自己编译Spark自己编译啥意思呀?
spark-2.4.5-bin-cdh5.16.2-2.11.tgz
2、部署模式
- 本地模式
- 一般用于测试开发,没有分布式的主从架构
- 将程序直接在本地启动一个JVM来运行
- 集群模式
- 一般用于生产环境,有分布式主从架构
- 将程序提交给分布式资源平台去运行
- 第一种:Standalone
- Spark自带的集群资源管理
- 第二种:YARN
- 将Spark程序提交给YARN运行
Deploying部署:
3、架构组成
-
主从架构模式
- 主节点:管理集群
- 从节点:负责实现计算
-
Standalone
- 主:Master
- 从:Worker
-
YARN
- 主:ResourceManger
- 从:NodeManager
zookeeper解决单点故障问题,那么就自己实现了单点故障解决问题的功能
4、本地模式(Local)
[root@node1 spark]# hadoop-daemon.sh start namenode
[root@node1 spark]# hadoop-daemon.sh start datanode
#node1:50070端口
-
参考附录一导入虚拟机
-
参考附录二安装本地环境
- 第一台机器恢复到快照3
- 启动第一台机器即可
-
启动HDFS
hadoop-daemon.sh start namenode hadoop-daemon.sh start datanode
-
测试
-
启动Spark-shell
cd /export/server/spark bin/spark-shell --master local[2]
- spark-shell是Spark提供的一个交互式的Spark程序,可以通过命令行直接写Spark代码
- –master:指定程序运行在哪个模式上
- local:表示本地模式
- [2]:运行这个程序,给定几核CPU
-
创建测试文件
hdfs dfs -mkdir /datas vim wordcount.data
hadoop spark hbase hive hive hive hive hadoop spark spark
hdfs dfs -put wordcount.data /datas #此文件在本地-》放到hdfs上
- 观察Spark-shell日志 ```shell Setting default log level to "WARN". #默认日志级别为WARN级别 To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel). #如果你要修改日志级别,你要sc.setLogLevel(“INFO”) Spark context Web UI available at http://node1.itcast.cn:4040 #每一个Spark程序都会自动开放一个Web监控界面,端口从4040开始,第二个程序的端口4041,依次类推 Spark context available as 'sc' (master = local[2], app id = local-1608102687971). #创建了一个对象:sc:SparkContext Spark session available as 'spark'. #创建了一个对象:spark:SparkSession
- SparkContext对象就是上午提到的driver programe
- SparkSession对象是新一代的driver programe:里面包含了一个SparkContext对象
- 用于替代老的SparkContext
-
-
测试WordCount
-
Input:读HDFS中/datas/wordcount.data
//调用sparkContext的方法读HDFS文件,存入RDD对象中 scala> val inputRdd = sc.textFile("/datas/wordcount.data") inputRdd: org.apache.spark.rdd.RDD[String] = /datas/wordcount.data MapPartitionsRDD[1] at textFile at <console>:24 //查看RDD的第一行数据 scala> inputRdd.first res0: String = hadoop spark hbase //统计RDD的行数 scala> inputRdd.count res1: Long = 3
- Transform:实现词频统计 - flatMap:RDD[String] ```scala scala> inputRdd.flatMap(line => line.trim.split("\\s+")) res2: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[2] at flatMap at <console>:26 scala> inputRdd.flatMap(line => line.trim.split("\\s+")).foreach(println) hadoop spark hbase hive hive hive hive hadoop spark spark
- map:RDD[(String,Int)] ``` scala> inputRdd.flatMap(line => line.trim.split("\\s+")).map(word => (word,1)).foreach(println) (hadoop,1) (spark,1) (hbase,1) (hive,1) (hive,1) (hive,1) (hive,1) (hadoop,1) (spark,1) (spark,1) ``` - reduceByKey:功能 = groupByKey + reduce:RDD[(String, Int)] ``` scala> val rsRDD = inputRdd.flatMap(line => line.trim.split("\\s+")).map(word => (word,1)).reduceByKey((tmp,item)=> tmp+item) rsRDD: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[8] at reduceByKey at <console>:25 scala> rsRDD.foreach(println) (hive,4) (spark,3) (hadoop,2) (hbase,1) ```
- Output
rsRDD.saveAsTextFile("/datas/output/output1")
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L55rTm6D-1610365374480)(Day38_分布式计算平台Spark:基础入门.assets/image-20201216155243915.png)]
-
测试运行Jar包
-
spark-submit:用于运行Spark的jar包的
-
YARN语法
yarn jar xxxx.jar main_class args
-
-
Spark
spark-submit [选项] --class 指定运行哪个类 xxxx.jar args
SPARK_HOME=/export/server/spark ${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 \ 10
-
-
5、集群模式(Standalone)
-
参考附录三安装集群环境
-
先将第一台机器恢复到快照4
-
-
启动Spark Standalone集群
-
启动HDFS:第一台机器执行
start-dfs.sh #创建一个目录,用于存储Spark程序的运行日志 hdfs dfs -mkdir -p /spark/eventLogs/
-
启动Master:第一台机器
/export/server/spark/sbin/start-master.sh
-
启动Worker:第一台机器
/export/server/spark/sbin/start-slaves.sh
-
查看WebUI
node1:8080
-
启动HistoryServer
start-dfs.sh /export/server/spark/sbin/start-history-server.sh
-
访问WebUI
node1:18080
-
-
测试
SPARK_HOME=/export/server/spark ${SPARK_HOME}/bin/spark-submit \ --master spark://node1:7077 \ --class org.apache.spark.examples.SparkPi \ ${SPARK_HOME}/examples/jars/spark-examples_2.11-2.4.5.jar \ 10
6、HA集群
-
关闭所有Spark进程
/export/server/spark/sbin/stop-slaves.sh /export/server/spark/sbin/stop-master.sh /export/server/spark/sbin/stop-history-server.sh
-
修改配置文件
cd /export/server/spark/conf/ vim spark-env.sh
#注释60行 #SPARK_MASTER_HOST=node1 #添加68行 SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=node1:2181,node2:2181,node3:2181 -Dspark.deploy.zookeeper.dir=/spark-ha"
-
分发
cd /export/server/spark/conf scp -r spark-env.sh node2:$PWD scp -r spark-env.sh node3:$PWD
-
启动ZK
zookeeper-daemons.sh start zookeeper-daemons.sh status
-
启动Master
-
第一台
/export/server/spark/sbin/start-master.sh
-
第二台
/export/server/spark/sbin/start-master.sh
-
-
启动Worker
/export/server/spark/sbin/start-slaves.sh
-
测试
SPARK_HOME=/export/server/spark ${SPARK_HOME}/bin/spark-submit \ --master spark://node1:7077,node2:7077 \ --class org.apache.spark.examples.SparkPi \ ${SPARK_HOME}/examples/jars/spark-examples_2.11-2.4.5.jar \ 100
五、Spark应用组成
1、应用组件
-
Master:主节点进程
- 类似于YARN中的ResourceManger
- 管理集群以及所有从节点
- 接受客户端请求
-
Worker:从节点进程:计算节点
- 类似于YARN中的NodeManger
- Work进程运行机器上:每个Work都能使用这台机器的一定的CPU和内存
-
HistoryServer:历史服务进程
-
Executor:Task真正运行的计算的进程
- 类似于MapTask进程和ReduceTask进程
- MapReduce以进程的方式来处理数据
- Spark以线程的方式来实现数据处理
- 就是Task运行所在的进程
- 每个Executor运行在Work节点中
- 每个Work节点会分配CPU和内存给每个Executor
- 每个Work能用机器的1Core1GB
- 每个Work上要启动Executor:每个Executor需要1core 512M的资源
- 问:每个Worker上能启动几个Executor?、
- 类似于MapTask进程和ReduceTask进程
-
Task:每个线程所处理的任务,每个线程需要1coreCPU来完成
-
Driver:每个Spark程序都要包含的一个进程,在代码中是:SparkContext对象
- 负责解析构建所有Task
- 分配以及监控和所有Task的运行
2、Web监控
- Application:一个Application就是一个Spark程序
- job:一个程序中处理的单元
- 以前MapReduce:一个Application就是一个Job
- 现在Spark:一个Application可以多个job
- Stage:每个Job会划分为多个阶段,每个阶段会用多个Task来实现这个阶段的处理的过程:执行计划
- 为什么需要Stage?
- 程序是基于lazy模式构建RDD,最终触发job的运行,通过DAG可以根据执行计划来一步步执行
- stage的划分规则?
- 是否产生shuffle过程
- stage怎么变成Task呢?
- Stage中每个RDD的每个分区需要使用一个Task来运行处理
- 为什么需要Stage?
六、开发环境搭建测试
1、创建Maven工程引入依赖
- 附录四中依赖
2、WordCount开发
package bigdata.itcast.cn.spark.scala.wordcount
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
/**
* @ClassName SparkCoreWordCount
* @Description TODO 自己开发代码来实现Wordcount
* @Date 2020/12/16 17:22
* @Create By Frank
*/
object SparkCoreWordCount {
def main(args: Array[String]): Unit = {
/**
* step1:先构建SparkContext:初始化资源对象
*/
//构建一个SparkConf:用于管理当前程序的所有配置
val conf = new SparkConf()
//给当前程序设置一个名字
.setAppName(this.getClass.getSimpleName.stripSuffix("$"))
//设置当前程序运行的模式
.setMaster("local[2]")
//构建一个SparkContext对象
val sc = new SparkContext(conf)
//调整日志级别
sc.setLogLevel("WARN")
/**
* step2:处理数据
*/
//todo:1-读取数据
val inputRdd: RDD[String] = sc.textFile("/datas/wordcount.data")
//todo:2-处理数据
val rsRdd = inputRdd
.filter(line => null != line && line.trim.length >0)
.flatMap(line => line.trim.split("\\s+"))
.map(word => word -> 1)
.reduceByKey((tmp,item) => tmp+item)
//todo:3-保存结果
rsRdd.foreach(println)
/**
* step3:释放资源
*/
Thread.sleep(1000000L)
sc.stop()
}
}
3、基础模板开发
package bigdata.itcast.cn.spark.scala.mode
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
/**
* @ClassName SparkCoreMode
* @Description TODO SparkCore的基础模板
* @Date 2020/12/16 17:22
* @Create By Frank
*/
object SparkCoreMode {
def main(args: Array[String]): Unit = {
/**
* step1:先构建SparkContext:初始化资源对象
*/
//构建一个SparkConf:用于管理当前程序的所有配置
val conf = new SparkConf()
//给当前程序设置一个名字
.setAppName(this.getClass.getSimpleName.stripSuffix("$"))
//设置当前程序运行的模式
.setMaster("local[2]")
//构建一个SparkContext对象
val sc = new SparkContext(conf)
//调整日志级别
sc.setLogLevel("WARN")
/**
* step2:处理数据
*/
//todo:1-读取数据
//todo:2-处理数据
//todo:3-保存结果
/**
* step3:释放资源
*/
Thread.sleep(1000000L)
sc.stop()
}
}
4、TopKey开发
package bigdata.itcast.cn.spark.scala.topkey
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
/**
* @ClassName SparkCoreWordCount
* @Description TODO 取单词最多的前3个
* @Date 2020/12/16 17:22
* @Create By Frank
*/
object SparkCoreWordCountTopWord {
def main(args: Array[String]): Unit = {
/**
* step1:先构建SparkContext:初始化资源对象
*/
//构建一个SparkConf:用于管理当前程序的所有配置
val conf = new SparkConf()
//给当前程序设置一个名字
.setAppName(this.getClass.getSimpleName.stripSuffix("$"))
//设置当前程序运行的模式
.setMaster("local[2]")
//构建一个SparkContext对象
val sc = new SparkContext(conf)
//调整日志级别
sc.setLogLevel("WARN")
/**
* step2:处理数据
*/
//todo:1-读取数据
val inputRdd: RDD[String] = sc.textFile("/datas/wordcount.data")
//todo:2-处理数据
inputRdd
.filter(line => null != line && line.trim.length >0)
.flatMap(line => line.trim.split("\\s+"))
.map(word => word -> 1)
.reduceByKey((tmp,item) => tmp+item)
//排序方式一:sortByKey:按照Key进行排序
// .map(tuple => tuple.swap)
// .sortByKey(ascending = false)
//排序方式二:sortBy :指定按照哪个值进行排序
.sortBy(tuple => tuple._2,false)
.take(3)
.foreach(println)
//todo:3-保存结果
// rsRdd.foreach(println)
/**
* step3:释放资源
*/
Thread.sleep(1000000L)
sc.stop()
}
}
附录一:导入Spark环境虚拟机
1、拷贝三台机器
2、导入三台机器
3、启动三台机器
- 第二台、第三台启动会遇到这个报错,选择浏览
-
浏览中,选择第一台机器的vmx文件即可
4、Windows配置映射
192.168.88.100 node1.itcast.cn node1
192.168.88.101 node2.itcast.cn node2
192.168.88.102 node3.itcast.cn node3
附录二:本地模式安装
【以第一台机器为例】
-
解压安装
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
- 常见的目录
- bin:客户端命令
- sbin:集群管理命令,服务的启动和关闭
- conf:配置文件目录
- jars:存放jar包的目录
- 常见的目录
-
修改配置
-
spark-env.sh.template 配置环境变量的
cd /export/server/spark/conf mv spark-env.sh.template spark-env.sh vim spark-env.sh
#22行-23行 JAVA_HOME=/export/server/jdk SCALA_HOME=/export/server/scala #30行 HADOOP_CONF_DIR=/export/server/hadoop/etc/hadoop
附录三:Standalone集群模式
1、恢复三台机器快照
-
架构:分布式主从架构
- 主:Master
- 第一台机器
- 从:Worker
- 三台机器
- 主:Master
-
将三台机器恢复到《4、分布式环境》
-
解压安装
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
2、修改进程配置
-
spark-env.sh
cd /export/server/spark/conf/ mv spark-env.sh.template spark-env.sh vim spark-env.sh
#22行-23行 JAVA_HOME=/export/server/jdk SCALA_HOME=/export/server/scala #30行 HADOOP_CONF_DIR=/export/server/hadoop/etc/hadoop #60行 #指定Master启动的地址 SPARK_MASTER_HOST=node1 #指定Master的通信端口 SPARK_MASTER_PORT=7077 #Master的Web端口 SPARK_MASTER_WEBUI_PORT=8080 #指定每个Work能使用这台机器的多少核CPU SPARK_WORKER_CORES=1 #指定每个Work能使用这台机器的多少内存 SPARK_WORKER_MEMORY=1g #Work的端口 SPARK_WORKER_PORT=7078 #Work的web端口 SPARK_WORKER_WEBUI_PORT=8081 #配置Spark程序日志的记录位置 SPARK_HISTORY_OPTS="-Dspark.history.fs.logDirectory=hdfs://node1:8020/spark/eventLogs/ -Dspark.history.fs.cleaner.enabled=true"
- MapReduce:JobHistoryServer
- 用于记录之前所运行的所有MapReduce的程序
- Spark:HistoryServer
- 用于记录Spark中运行的所有程序,会将所有程序运行的日志存储在HDFS上
- MapReduce:JobHistoryServer
-
spark-defaults.conf:类似于我们以前讲的site文件
cd /export/server/spark/conf/ hdfs dfs -mkdir -p /spark/eventLogs/ mv spark-defaults.conf.template spark-defaults.conf vim spark-defaults.conf
#28行 #启用日志存储 spark.eventLog.enabled true #日志存储位置 spark.eventLog.dir hdfs://node1:8020/spark/eventLogs/ #启用压缩存储日志 spark.eventLog.compress true
3、修改Worker配置
cd /export/server/spark/conf/
mv slaves.template slaves
vim slaves
node1
node2
node3
4、日志级别调整
cd /export/server/spark/conf/
mv log4j.properties.template log4j.properties
vim log4j.properties
#修改19行
log4j.rootCategory=WARN, console
5、分发
-
所有节点配置免秘钥登录
ssh-copy-id node1 ssh-copy-id node2 ssh-copy-id node3
-
分发Spark
cd /export/server/ scp -r spark-2.4.5-bin-cdh5.16.2-2.11 node2:$PWD scp -r spark-2.4.5-bin-cdh5.16.2-2.11 node3:$PWD
-
第二台和第三台创建软连接
ln -s /export/server/spark-2.4.5-bin-cdh5.16.2-2.11 /export/server/spark
附录四:Spark Maven依赖
<!-- 指定仓库位置,依次为aliyun、cloudera和jboss仓库 -->
<repositories>
<repository>
<id>aliyun</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
<repository>
<id>jboss</id>
<url>http://repository.jboss.com/nexus/content/groups/public</url>
</repository>
</repositories>
<properties>
<scala.version>2.11.12</scala.version>
<scala.binary.version>2.11</scala.binary.version>
<spark.version>2.4.5</spark.version>
<hadoop.version>2.6.0-cdh5.16.2</hadoop.version>
</properties>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_${scala.binary.version}</artifactId>
<version>${spark.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>${hadoop.version}</version>
</dependency>
</dependencies>
<build>
<outputDirectory>target/classes</outputDirectory>
<testOutputDirectory>target/test-classes</testOutputDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<!-- Maven 编译的插件 -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>