Spark 介绍
行业广泛使用Hadoop来分析他们的数据集。原因是Hadoop框架基于一个简单的编程模型(MapReduce),它支持可扩展,灵活,容错和成本有效的计算解决方案。这里,主要关注的是在处理大型数据集时在查询之间的等待时间和运行程序的等待时间方面保持速度。
Spark由Apache Software Foundation引入,用于加速Hadoop计算软件过程。
对于一个普遍的信念,Spark不是Hadoop的修改版本,并不是真的依赖于Hadoop,因为它有自己的集群管理。
Spark以两种方式使用Hadoop : 一个是存储,另一个是处理。由于Spark具有自己的集群管理计算,因此它仅使用Hadoop进行存储。
Apache Spark是一种快速的集群计算技术,专为快速计算而设计。它基于Hadoop MapReduce,它扩展了MapReduce模型,
以有效地将其用于更多类型的计算,包括交互式查询和流处理。
Spark的主要特性是它的内存中集群计算,提高了应用程序的处理速度。
1.Apache Spark的特性:
a.速度:在迭代循环的计算模型下,spark比Hadoop快100倍,在磁盘运行spark比hadoop快10倍;
b.易用性:spark提供多种语言的API,如Java、Python、Scala、R、SQL等
c.扩展性:在spark RDD基础上,提供一整套的分析计算模型:spark SQL、spark Stresaming、spark MLlib 和 GraphX;
d.运行: spark支持在 Hadoop, Apache Mesos, Kubernetes, standalone, or in the cloud.
2.Spark的组件:
1)Apache Spark Core
Spark Core是spark平台的基础通用执行引擎,所有其他功能都是基于Spark Core。它在外部存储系统中提供内存计算和引用数据集。
2)Spark SQL
Spark SQL是Spark Core之上的一个组件,它引入了一个称为SchemaRDD的新数据抽象,它为结构化和半结构化数据提供支持。
3)Spark Streaming
Spark Streaming利用Spark Core的快速调度功能来执行流式分析。它以小批量获取数据,并对这些小批量的数据执行RDD(弹性分布式数据集)转换。
4)MLlib (Machine Learning Library)
MLlib是Spark之上的分布式机器学习框架,因为基于分布式内存的Spark架构。根据基准,它是由MLlib开发人员针对交替最小二乘法(ALS)实现完成的。
Spark MLlib是基于Hadoop磁盘的Apache Mahout版本的9倍(在Mahout获得了Spark接口之前)。
5) GraphX
GraphX是Spark上的一个分布式图形处理框架。它提供了一个用于表达图形计算的API,可以通过使用Pregel抽象API为用户定义的图形建模。它还为此抽象提供了一个优化的运行时。
3.Spark RDD 弹性分布式数据集(简单了解)
弹性分布式数据集(RDD)是Spark的基本数据结构。
它是一个不可变的分布式对象集合。 RDD中的每个数据集划分为逻辑分区,可以在集群的不同节点上计算。
RDD可以包含任何类型的Python,Java或Scala对象,包括用户定义的类。
有3种方法来创建RDD: 1)并行化驱动程序中的现有集合 2)引用外部存储系统中的数据集 3)调用SparkContext对象的 makeRDD() 方法
4.MapReduce中的数据共享及迭代操作与Spark RDD中的数据共享及迭代操作
Spark多种运行模式:
Local模式
Cluster模式 :standalone,Yarn,Messos(国内很少用)
5.spark的Local模式:
0).版本选型:spark2.1.2。依赖scala2.11.8
1).下载spark2.1.2.tar.gz
2).解压安装:
$>cd /home/hyxy/apps/
$>cp /mnt/hgfs/2.安装环境/download/apache-spark/spark-2.1.2-bin-hadoop2.7.tgz .
$>tar -zxvf spark-2.1.2-bin-hadoop2.7.tgz
$>ln -s spark-2.1.2-bin-hadoop2.7 spark
3).配置环境变量
修改【~/.bash_profile】,在文件尾部追加以下内容:
#spark install
export SPARK_HOME=/home/hyxy/soft/spark
export PATH=$SPARK_HOME/bin:$SPARK_HOME/sbin:$PATH
$>source ~/.bash_profile
4).至此,单机版搭建完成!
$>spark-shell
访问WebUI:HTTP://master:4040
Spark context Web UI available at http://192.168.179.130:4040
Spark context available as 'sc' (master = local[*], app id = local-1558318902046).
sc:代表 Spark context上下文对象
master:本地模式
local[*]:开启线程数
$>spark-shell local[4] --->spark并行处理4个线程,可以理解为4个节点同时在运行,
用线程的方式模拟集群运行 默认并行度是1
$>spark-shell --master local[3]
Spark session available as 'spark'.
spark:spark会话对象,用来操作sparkSQL的对象
$>spark-shell scala操作:
scala> 1+3
res0: Int = 4
5):quit 退出
通过另外窗口查看单机启动的spark进程 jps
发现:多了一个SparkSubmit
查看自带的案例:
$> cd ~/apps/spark/examples/src/main/scala/org/apache/spark/examples/
$> cat SparkPi.scala
运行spark自带案例 10:代表开10个线程去算
source ~/.bash_profile
$> run-example SparkPi 10
Pi is roughly 3.1392631392631394
1**)加载本地文件:
$ cat /home/hyxyaaa.txt
aa111
jehello word a
hello hyxy
scala> val lines = sc.textFile("file:///home/hyxy/aaa.txt")
lines: org.apache.spark.rdd.RDD[String] = file:///home/hyxy/aaa.txt MapPartitionsRDD[1] at textFile at <console>:24
//总记录数
scala> lines.count
res0: Long = 3
scala> lines.first
res1: String = aa111
练习:Local模式 运行wordcount案例
vim qqq.txt
hello word hello hyxy
hello aaa .....
scala> val lines=sc.textFile("file:///home/hyxy/Desktop/qqq.txt")
scala> lines.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).sortBy(_._2,false).collect
【本地模式查看README.md】
val lines = sc.textFile("file:///home/hyxy/soft/spark/README.md")
scala> lines.count
res1: Long = 104
scala> lines.filter(line => line.contains("Spark")).count()
---------------------------------------------------------------------------------------------------------------------
6.Cluster模式 :standalone,Yarn,Mesos(国内很少用)
说明:【如果现有的集群框架中存在MR的相关应用,同时相关的MR无法转换为Spark应用的,集群选型为Spark On Yarn;
如果现有的集群框架中只有Spark应用,那么建议采用spark Standalone模式】
1.spark可以运行在不同的计算引擎上,所以集群模式安装分不同种情况:
说明:spark的Standalone模式和Spark on Yarn占比 较多。
a.spark的standalone集群模式安装
【standalone:由spark自己来完成资源的管理与调度】
standalone:主从架构 -- >master worker
复制三个文件,并修改:
$>cp spark-env.sh.template spark-env.sh
添加以下内容,master节点是Master(主) 注意:"="附近无空格:
export JAVA_HOME=/home/hyxy/apps/jdk
export SPARK_MASTER_HOST=master
export SPARK_MASTER_PORT=7077
$>cp slaves.template slaves
添加工作节点(Worker 从----添加之前要删除 localhost 该行),如下:
master
slave1
slave2
$>cp spark-defaults.conf.template spark-defaults.conf
2.远程scp复制spark安装目录至其它节点:slave1和slave2;
$>scp -r ~/apps/spark-2.1.2-bin-hadoop2.7/ hyxy@slave1:/home/hyxy/apps/
$>ln -s spark-2.1.2-bin-hadoop2.7 spark //在Slave1节点上
$>scp -r ~/apps/spark-2.1.2-bin-hadoop2.7/ hyxy@slave2:/home/hyxy/apps/
$>ln -s spark-2.1.2-bin-hadoop2.7 spark //在Slave2节点上
3.分别修改slave1、slave2等的环境变量;
全部启动:
start-all.sh 启动master 和 slaves。但是该命令和我们hdfs是一样的, 所以这里需要进入bin目录下./start-all.sh
查看sbin下 start-all.sh --》
# Load the Spark configuration
. "${SPARK_HOME}/sbin/spark-config.sh"
# Start Master
"${SPARK_HOME}/sbin"/start-master.sh
# Start Workers
"${SPARK_HOME}/sbin"/start-slaves.sh
4.开启spark Standalone集群的守护进程:
[hyxy@master] >start-master.sh //开启spark的Master守护进程
[hyxy@master] >start-slaves.sh //开启spark的Worker守护进程
[hyxy@master conf]$ jps
3522 Master
3659 Jps
3615 Worker
5.测试
访问WebUI界面:http://master:8080/ (rpc :spark://master:7077 )
$>spark-shell --master spark://master:7077
观察WebUI的网页说明;
------------------------------------------------------------------------------------------------------------------
可以在不同的节点连接spark-shell
1) master (master节点启动) spark-shell --master spark://master:7077
http://master:8080/ Running Applications
2) slave1 (work节点启动) spark-shell --master spark://master:7077
http://master:8080/ Running Applications
3) slave2 (work节点启动) spark-shell --master spark://master:7077
http://master:8080/ Running Applications
saprk的Standalone默认job的队列模式是采用先进先出的方式:
master启动--> slave1启动 -->master运行 count -->slave1运行 count (报错)-->master:q -->slave1运行 count正常
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Standalone模式查看README.md:
val lines = sc.textFile("file:///home/hyxy/soft/spark/README.md")
scala> lines.count
res1: Long = 104
--------------------------------------------------------------------------------------------
拷贝文件home/hyxy/soft/spark/README.md放到 /home/hyxy/Desktop/下
a)本地模式查看README.md
val lines = sc.textFile("file:///home/hyxy/Desktop/README.md")
b)Standalone模式查看README.md
val lines = sc.textFile("file:///home/hyxy/Desktop/README.md")
c)slave1 slave2 拷贝文件home/hyxy/apps/spark/README.md放到 /home/hyxy/Desktop/下
Standalone模式查看README.md
val lines = sc.textFile("file:///home/hyxy/Desktop/README.md")
总结:
在Standalone模式下, 加载文件是每个集群本地的文件,所以此模式不适合加载本地文件,需要将文件放到hdfs上
2**)加载集群文件(若加载集群上的文件,active 节点上的文件才能执行行动成功)
开启服务: zkServer.sh start start-dfs.sh start-master.sh start-slaves.sh
[hyxy@master conf]$ hadoop fs -lsr /
lsr: DEPRECATED: Please use 'ls -R' instead.
-rw-r--r-- 3 hyxy supergroup 43 2019-04-24 10:32 /a1.txt
-rw-r--r-- 3 hyxy supergroup 43 2019-04-24 10:33 /a2.txt
[hyxy@master conf]$ hadoop fs -cat /a1.txt
hello word hello hyxy
hello aaa
hello bbb
scala> val lines = sc.textFile("hdfs://master:9000/input/input1.txt")
lines: org.apache.spark.rdd.RDD[String] = hdfs://master:9000/a1.txt MapPartitionsRDD[7] at textFile at <console>:24
scala> lines.count
org.apache.hadoop.ipc.RemoteException: Operation category READ is not supported in state standby (active的节点可访问)
找到集群active节点******* slave1 *******
scala> val lines = sc.textFile("hdfs://slave1:9000/a1.txt")
lines: org.apache.spark.rdd.RDD[String] = hdfs://slave1:9000/a1.txt MapPartitionsRDD[9] at textFile at <console>:24
scala> lines.count
res3: Long = 3
返回包含"aaa"的行数
scala> lines.filter(x=>x.contains("aaa"))
res6: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[3] at filter at <console>:27
scala> res6.count
res7: Long = 1
================================================================================================
7.Spark on Yarn集群模式安装(master:ResourceManager slaves:NodeManager)
停止saprk:stop-master.sh stop-slaves.sh
【Spark on Yarn:由yarn来完成资源的管理与调度】
1).修改spark-env.sh文件,添加以下内容:
export HADOOP_CONF_DIR=/home/hyxy/apps/hadoop/etc/hadoop
分发所有节点 slave1 slave2
2).测试:
开启hadoop:
$>zkserver.sh start
$>start-dfs.sh
$>start-yarn.sh
$>start-master.sh
$>start-slaves.sh
启动spark:
$>spark-shell --master yarn-client
3).注意:抛异常,资源调用超出上限,修改默认校验 修改为不校验
ERROR spark.SparkContext: Error initializing SparkContext.
org.apache.spark.SparkException: Yarn application has already ended! It might have been killed or unable to launch application master.
停止spark服务器, yarn服务器:
[hyxy@master conf]$ stop-master.sh
stopping org.apache.spark.deploy.master.Master
[hyxy@master conf]$ stop-slave.sh
stopping org.apache.spark.deploy.worker.Worker
[hyxy@master conf]$ stop-yarn.sh
修改{HADOOP_HOEM/etc/hadoop}/yarn-site.xml 增加以下内容:
<property>
<name>yarn.nodemanager.pmem-check-enabled</name>
<value>false</value>
<description>是否将强制执行物理内存限制容器。</description>
</property>
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
1) 分发至集群其它节点
$>scp yarn-site.xml hyxy@slave1:/home/hyxy/apps/hadoop/etc/hadoop/
$>scp yarn-site.xml hyxy@slave2:/home/hyxy/apps/hadoop/etc/hadoop/
2)重启$>start-yarn.sh
$>start-master.sh
$>start-slaves.sh
$>spark-shell --master yarn-client
查看yarnWebUI 因为spark是由yarn来管理: http://master:8088/cluster
application_1558335871742_0001 hyxy Spark shell SPARK
1.每个Spark应用都由一个驱动器程序(driver program:Shell窗口)来发起集群上的各种并行操作
2.hadoop的一个mr对应一个job
spark的一个spark shell 对应一个job,这个job可以运行多个应用
总结:启动spark三种不同的方式,Spark on yarn,缺点慢!
***只有standonly模式有work的概念,
on yarn模式由nodemanager来代替work来计算***
Spark应用都由一个驱动器程序(driver program:Shell)来发起集群上的各种并行操作,
eg: spark-shell 将来我们用main函数
两种方式获得sc对象:
1)spark shell: 直接可以用sc对象
2)javaAPI:先创建SparkConf,再通过SparkConf创建SparkContext
val conf = new SparkConf().setAppName("demo").setMaster("local")
val sc = new SparkContext(conf)
总结:不同的程序在不同的集群下运行,结果不同
——————————————————————————————
练习: 找出文本文件中,单行文本所包含的单词数量的最大值(6)
hello word hello word hyxy11
hello aaa aaa aaa aaa aaa
hello bbb
hello bbb