上传解压安装包
上传spark-2.1.1-bin-hadoop2.7.tgz安装包到Linux上
解压安装包到指定位置
tar -xf spark-2.1.1-bin-hadoop2.7.tgz -C /home/bigdata/Hadoop
Spark的部署模式有Local、Local-Cluster、Standalone、Yarn、Mesos,我们选择最具代表性的Standalone集群部署模式。
进入到Spark安装目录
cd /home/bigdata/hadoop/spark-2.1.1-bin-hadoop2.7/conf
将slaves.template复制为slaves
将spark-env.sh.template复制为spark-env.sh
修改slave文件,将work的hostname输入:
修改spark-env.sh文件,添加如下配置:
Spark集群配置完毕,目前是1个Master,2个Work,master01上启动Spark集群
/home/bigdata/hadoop/spark-2.1.1-bin-hadoop2.7/sbin/start-all.sh
启动后执行jps命令,主节点上有Master进程,其他子节点上有Work进行,登录Spark管理界面查看集群状态(主节点):http://master01:8080/
到此为止,Spark集群安装完毕.
注意:如果遇到 “JAVA_HOME not set” 异常,可以在sbin目录下的spark-config.sh 文件中加入如下配置:
export JAVA_HOME=XXXX
进入到Spark安装目录
cd /home/bigdata/hadoop/spark-2.1.1-bin-hadoop2.7/conf
将spark-default.conf.template复制为spark-default.conf
修改spark-default.conf文件,开启Log:
【注意:HDFS上的目录需要提前存在】
修改spark-env.sh文件,添加如下配置:
在HDFS上创建好你所指定的eventLog日志目录。
spark-defaults.conf
spark.eventLog.enabled true
spark.eventLog.dir hdfs://master01:9000/directory
spark.eventLog.compress true
spark-env.sh
export SPARK_HISTORY_OPTS="-Dspark.history.ui.port=4000
-Dspark.history.retainedApplications=3
-Dspark.history.fs.logDirectory=hdfs://master01:9000/directory"
参数描述:
spark.eventLog.dir:Application在运行过程中所有的信息均记录在该属性指定的路径下;
spark.history.ui.port=4000 调整WEBUI访问的端口号为4000
spark.history.fs.logDirectory=hdfs://master01:9000/directory 配置了该属性后,在start-history-server.sh时就无需再显式的指定路径,Spark History Server页面只展示该指定路径下的信息
spark.history.retainedApplications=3 指定保存Application历史记录的个数,如果超过这个值,旧的应用程序信息将被删除,这个是内存中的应用数,而不是页面上显示的应用数。
将配置好的Spark文件拷贝到其他节点上
/home/bigdata/hadoop/spark-2.1.1-bin-hadoop2.7/sbin/start-all.sh
/home/bigdata/hadoop/spark-2.1.1-bin-hadoop2.7/sbin/start-history-server.sh
到此为止,Spark History Server安装完毕.
如果遇到Hadoop HDFS的写入权限问题:
org.apache.hadoop.security.AccessControlException
解决方案: 在hdfs-site.xml中添加如下配置,关闭权限验证
<property>
<name>dfs.permissionsname>
<value>falsevalue>
property>
集群部署完了,但是有一个很大的问题,那就是Master节点存在单点故障,要解决此问题,就要借助zookeeper,并且启动至少两个Master节点来实现高可靠,配置方式比较简单:
Spark集群规划:master01,master02是Master;slave01,slave02,slave03是Worker
安装配置Zookeeper集群,并启动Zookeeper集群
停止spark所有服务,修改配置文件spark-env.sh,在该配置文件中删掉SPARK_MASTER_IP并添加如下配置
export SPARK_DAEMON_JAVA_OPTS="
-Dspark.deploy.recoveryMode=ZOOKEEPER
-Dspark.deploy.zookeeper.url=zk1,zk2,zk3
-Dspark.deploy.zookeeper.dir=/spark"
1.在 master01节点上修改spark-env.sh配置文件
2.将配置文件同步到所有节点。
3.在master01上执行sbin/start-all.sh脚本,启动集群并启动第一个master节点,然后在master02上执行sbin/start-master.sh启动第二个master节点。
4.程序中spark集群的访问地址需要改成:
spark://master01:port1,master02:port2
【Zookeeper中保存了什么?】
[bigdata@master01 zookeeper-3.4.10]$ bin/zkCli.sh -server master01:2181,slave01:2181,slave02:2181
<configuration>
<property>
<name>yarn.resourcemanager.hostnamename>
<value>master01value>
property>
<property>
<name>yarn.nodemanager.aux-servicesname>
<value>mapreduce_shufflevalue>
property>
<property>
<name>yarn.nodemanager.pmem-check-enabledname>
<value>falsevalue>
property>
<property>
<name>yarn.nodemanager.vmem-check-enabledname>
<value>falsevalue>
property>
configuration>
修改Spark-env.sh 添加:
让Spark能够发现Hadoop配置文件
HADOOP_CONF_DIR=/home/bigdata/hadoop/hadoop-2.7.3/etc/hadoop
YARN_CONF_DIR=/home/bigdata/hadoop/hadoop-2.7.3/etc/hadoop
/home/bigdata/hadoop/spark-2.1.1-bin-hadoop2.7/bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master spark://master01:7077 \
--executor-memory 1G \
--total-executor-cores 2 \
/home/bigdata/hadoop/spark-2.1.1-bin-hadoop2.7/examples/jars/spark-examples_2.11-2.1.1.jar \
100
参数说明:
–master spark://master01:7077 指定Master的地址
–executor-memory 1G 指定每个executor可用内存为1G
–total-executor-cores 2 指定每个executor使用的cup核数为2个
该算法是利用蒙特•卡罗算法求PI
/home/bigdata/hadoop/spark-2.1.1-bin-hadoop2.7/bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode client \
/home/bigdata/hadoop/spark-2.1.1-bin-hadoop2.7/examples/jars/spark-examples_2.11-2.1.1.jar \
100
一旦打包好,就可以使用bin/spark-submit脚本启动应用了. 这个脚本负责设置spark使用的classpath和依赖,支持不同类型的集群管理器和发布模式:
./bin/spark-submit \
--class <main-class>
--master <master-url> \
--deploy-mode <deploy-mode> \
--conf <key>=<value> \
... # other options
<application-jar> \
[application-arguments]
- –class: 你的应用的启动类 (如 org.apache.spark.examples.SparkPi)
- –master: 集群的master URL (如 spark://23.195.26.187:7077)
- –deploy-mode: 是否发布你的驱动到worker节点(cluster) 或者作为一个本地客户端 (client) (default: client)*
- –conf: 任意的Spark配置属性, 格式key=value. 如果值包含空格,可以加引号“key=value”. 缺省的Spark配置
- application-jar: 打包好的应用jar,包含依赖. 这个URL在集群中全局可见。 比如hdfs:// 共享存储系统, 如果是 file:// path, 那么所有的节点的path都包含同样的jar.
- application-arguments: 传给main()方法的参数
Master URL 可以是以下格式:
查看Spark-submit全部参数:
local 本地以一个worker线程运行(例如非并行的情况).
local[K] 本地以K worker 线程 (理想情况下, K设置为你机器的CPU核数).
local[*] 本地以本机同样核数的线程运行.
spark://HOST:PORT 连接到指定的Spark standalone cluster master. 端口是你的master集群配置的端口,缺省值为7077.
mesos://HOST:PORT 连接到指定的Mesos 集群. Port是你配置的mesos端口, 缺省是5050. 或者如果Mesos使用ZOoKeeper,格式为 mesos://zk://…
yarn-client 以client模式连接到YARN cluster. 集群的位置基于HADOOP_CONF_DIR 变量找到.
yarn-cluster 以cluster模式连接到YARN cluster. 集群的位置基于HADOOP_CONF_DIR 变量找到.
/home/bigdata/hadoop/spark-2.1.1-bin-hadoop2.7/bin/spark-shell \
--master spark://master01:7077 \
--executor-memory 2g \
--total-executor-cores 2
注意:
如果启动spark shell时没有指定master地址,但是也可以正常启动spark shell和执行spark shell中的程序,其实是启动了spark的local模式,该模式仅在本机启动一个进程,没有与集群建立联系。
Spark Shell中已经默认将SparkContext类初始化为对象sc。用户代码如果需要用到,则直接应用sc即可
首先启动hdfs
将Spark目录下的RELEASE文件上传一个文件到hdfs://master01:9000/RELEASE
~/hadoop/hadoop-2.7.3/bin/hdfs dfs -put ./RELEASE /
在Spark shell中用scala语言编写spark程序
sc.textFile("hdfs://master01:9000/RELEASE").flatMap(_.split(" "))
.map((_,1)).reduceByKey(_+_).saveAsTextFile("hdfs://master01:9000/out")
hdfs dfs -cat hdfs://master01:9000/out/p*
说明:
sc是SparkContext对象,该对象时提交spark程序的入口
textFile(hdfs://master01:9000/RELEASE)是hdfs中读取数据
flatMap(.split(" "))先map在压平
map((,1))将单词和1构成元组
reduceByKey(+)按照key进行reduce,并将value累加
saveAsTextFile(“hdfs:// master01:9000/out”)将结果写入到hdfs中
spark shell仅在测试和验证我们的程序时使用的较多,在生产环境中,通常会在IDE中编制程序,然后打成jar包,然后提交到集群,最常用的是创建一个Maven项目,利用Maven来管理jar包的依赖。
配置Maven的pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>sparkartifactId>
<groupId>com.atguigugroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>wordcountartifactId>
<dependencies>
<dependency>
<groupId>org.scala-langgroupId>
<artifactId>scala-libraryartifactId>
<version>${scala.version}version>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.apache.sparkgroupId>
<artifactId>spark-core_2.11artifactId>
<version>${spark.version}version>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.apache.hadoopgroupId>
<artifactId>hadoop-clientartifactId>
<version>${hadoop.version}version>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>jcl-over-slf4jartifactId>
<version>${slf4j.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
<version>${slf4j.version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
<version>${slf4j.version}version>
dependency>
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>${log4j.version}version>
dependency>
dependencies>
<build>
<finalName>wordcountfinalName>
<plugins>
<plugin>
<groupId>net.alchim31.mavengroupId>
<artifactId>scala-maven-pluginartifactId>
<version>3.2.2version>
<executions>
<execution>
<goals>
<goal>compilegoal>
<goal>testCompilegoal>
goals>
execution>
executions>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-assembly-pluginartifactId>
<version>3.0.0version>
<configuration>
<archive>
<manifest>
<mainClass>com.atguigu.spark.WordCountmainClass>
manifest>
archive>
<descriptorRefs>
<descriptorRef>jar-with-dependenciesdescriptorRef>
descriptorRefs>
configuration>
<executions>
<execution>
<id>make-assemblyid>
<phase>packagephase>
<goals>
<goal>singlegoal>
goals>
execution>
executions>
plugin>
plugins>
build>
project>
编写spark程序
package com.atguigu.spark
import org.apache.spark.{SparkConf, SparkContext}
import org.slf4j.LoggerFactory
/**
* Created by wuyufei on 31/07/2017.
*/
object WordCount {
val logger = LoggerFactory.getLogger(WordCount.getClass)
def main(args: Array[String]) {
//创建SparkConf()并设置App名称
val conf = new SparkConf().setAppName("WC")
//创建SparkContext,该对象是提交spark App的入口
val sc = new SparkContext(conf)
//使用sc创建RDD并执行相应的transformation和action
sc.textFile(args(0)).flatMap(_.split(" ")).map((_, 1)).reduceByKey(_+_, 1).sortBy(_._2, false).saveAsTextFile(args(1))
//停止sc,结束该任务
logger.info("complete!")
sc.stop()
}
}
使用Maven打包:首先修改pom.xml中的main class
点击idea右侧的Maven Project选项,点击Lifecycle,选择clean和package,然后点击Run Maven Build
选择编译成功的jar包,并将该jar上传到Spark集群中的某个节点上
首先启动hdfs和Spark集群
启动hdfs
/home/bigdata/hadoop/hadoop-2.7.3/sbin/start-dfs.sh
启动spark
/home/bigdata/hadoop/spark-2.1.1-bin-hadoop2.7/sbin/start-all.sh
使用spark-submit命令提交Spark应用(注意参数的顺序)
/home/bigdata/hadoop/spark-2.1.1-bin-hadoop2.7/bin/spark-submit\
--class com.atguigu.spark.WordCount\
--master spark://master01:7077\
--executor-memory 1G \
--total-executor-cores 2 \
wordcount-jar-with-dependencies.jar\
hdfs://master01:9000/RELEASE\
hdfs://master01:9000/out
查看程序执行结果
hdfs dfs -cat hdfs://master01:9000/out/part-*
本地Spark程序调试需要使用local提交模式,即将本机当做运行环境,Master和Worker都为本机。运行时直接加断点调试即可。如下:
如果本机操作系统是windows,如果在程序中使用了hadoop相关的东西,比如写入文件到HDFS,则会遇到如下异常:
出现这个问题的原因,并不是程序的错误,而是用到了hadoop相关的服务,解决办法是将附加里面的hadoop-common-bin-2.7.3-x64.zip解压到任意目录。
在IDEA中配置Run Configuration,添加HADOOP_HOME变量
通过IDEA进行远程调试,主要是将IDEA作为Driver来提交应用程序,配置过程如下:
修改sparkConf,添加最终需要运行的Jar包、Driver程序的地址,并设置Master的提交地址: