安装前的准备
安装好Fully-distributed Hadoop的集群,安装Hadoop教程参考:
https://blog.youkuaiyun.com/lucylove3943/article/details/80589422
我目前在6台机子上搭了Hadoop-2.9.2,这是当前的配置:
Master Node: falcon-1
Slave Nodes: falcon-2, falcon-3, falcon-4, cat-2, cat-4
一些必要的安装工作
主要是两个东西:Scala 和 sbt。
Spark主要支持三种编程语言:scala, java, python. 其中scala是最主要的语言,sbt是用来打包scala程序的软件,类似于maven之于Java。
安装scala
我是在https://www.scala-lang.org/download/找到的scala下载地址。
我安装的版本是scala-2.10.4,找到tgz包的下载链接后,在命令行输入下述语句:
wget https://scala-lang.org/files/archive/scala-2.10.4.tgz
解压这个包:
tar -xzvf scala-2.10.4.tgz
修改bashrc文档:
vim ~/.bashrc
在文档中添加如下内容:
export SCALA_HOME=/home/qianwen/scala-2.10.4
export PATH=$PATH:$SCALA_HOME/bin
就是把SPARK_HOME赋值为当前scala的解压路径,然后添加path内容。如图所示:
接着source该文件:
source ~/.bashrc
此时在命令行输入以下命令,确认scala已经正确安装:
scala -version
此时命令行中如果出现如下内容,则说明安装成功:
安装sbt
我参考了一篇博客,使用的是apt-get安装的sbt。主要输入以下四行命令:
echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2EE0EA64E40A89B84B2DF73499E82A75642AC823
sudo apt-get update
sudo apt-get install sbt
正式安装Spark
下载spark
进入spark官网下载页面:http://spark.apache.org/downloads.html
点击如图所示红圈,进入spark-2.4.3的下载页面:
复制上图圈中链接,在命令行中输入
wget http://apache.mirrors.pair.com/spark/spark-2.4.3/spark-2.4.3-bin-hadoop2.7.tgz
解压该tgz包:
tar -xzvf spark-2.4.3-bin-hadoop2.7.tgz
进入spark配置文件夹,配置spark-env.sh文件:
cd spark-2.4.3-bin-hadoop2.7/conf/
cp spark-env.sh.template spark-env.sh
vim spark-env.sh
在里面添加如下内容:
export SPARK_HOME=/home/qianwen/spark-2.4.3-bin-hadoop2.7
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export HADOOP_HOME=/home/qianwen/hadoop-2.9.2
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export YARN_HOME=$HADOOP_HOME
export SCALA_HOME=/home/qianwen/scala-2.10.4
SPARK_MASTER_IP=falcon-1
SPARK_LOCAL_DIRS=/home/qianwen/spark-2.4.3-bin-hadoop2.7
SPARK_CONF_DIR=/home/qianwen/spark-2.4.3-bin-hadoop2.7/conf
SPARK_DRIVE_MEMORY=2G
for file in $SPARK_HOME/jars/*.jar
do
export CLASSPATH=$CLASSPATH:$file
done
然后source该文件:
source spark-env.sh
然后修改slaves文件:
cp slaves.template slaves
vim slaves
然后把Hadoop里配置的几个slave nodes都加进去;
falcon-2
falcon-3
falcon-4
cat-2
cat-4
输下述命令把配置好的spark发送到其他节点:
scp -r spark-2.4.3-bin-hadoop2.7 falcon-2:~
scp -r spark-2.4.3-bin-hadoop2.7 falcon-3:~
scp -r spark-2.4.3-bin-hadoop2.7 falcon-4:~
scp -r spark-2.4.3-bin-hadoop2.7 cat-2:~
scp -r spark-2.4.3-bin-hadoop2.7 cat-4:~
spark就这样安装好啦!
Spark例子
从易到难,我一共跑了以下几个例子:
1. spark-shell
2.spark自带例子,计算pi
3.wordcount client模式
4.wordcount spark yarn cluster模式
在跑例子前,先启动spark。
然后回到spark主目录,启动spark:
sbin/start-all.sh
启动成功后,在master node,也就是falcon-1上输入
jps
在master node上,看到的进程中master就是spark的进程。
在slave节点上,输入jps查看当前运行进程,其中worker是spark的进程。
(一)例子spark-shell
在命令行输入下述命令,进入spark的shell命令行界面,执行基本spark操作:
bin/spark-shell
此时应出现如下界面:
注意到这里出现了Spark context web UI available at http://falcon-1:4040。 可访问这个链接查看spark任务和集群的信息。
依次输入以下命令:
val lines = sc.textFile("README.md");
读取README.md中内容,存入RDD。
接着用下述命令计算README.md中一共有多少个单词:
lines.count()
最后用下述命令,查看README.md中第一行的内容:
lines.first()
最后可通过Ctrl+D推出spark-shell
(二)spark自带计算Pi的例子
在spark主目录下输入以下命令:
bin/run-example SparkPi 10 > Sparkpilog.txt
spark会开始执行任务,然后把结果输出到Sparkpilog.txt, 可通过如下命令查看计算结果:
cat Sparkpilog.txt
(三)打包运行wordcount (yarn-client模式)
首先进入hadoop主目录,启动hadoop:
sbin/start-dfs.sh
sbin/start-yarn.sh
由于现在是用的yarn来做cluster管理,所以进入spark目录,关闭spark的worker和master进程。
sbin/stop-all.sh
接着建一个文件夹spark_test,用来编辑wordcount代码和打包:
mkdir spark_test
cd spark_text
新建WordCount.scala文件:
vim WordCount.scala
然后在里面添加如下内容:
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
object WordCount {
def main(args: Array[String]) {
if (args.length < 1) {
System.err.println("Usage: <file>")
System.exit(1)
}
val conf = new SparkConf()
val sc = new SparkContext(conf)
val line = sc.textFile(args(0))
line.flatMap(_.split(" ")).map((_, 1)).reduceByKey(_+_).collect().foreach(println)
sc.stop()
}
}
这个代码是从命令行读取输入文件,然后最终结果是打印到控制台。
下一步就是build代码,build之前需要编辑build文档,类似于maven里的pom.xml:
vim build.sbt
添加以下内容:
name := "sparkScala"
version := "1.0"
scalaVersion := "2.10.4"
javacOptions ++= Seq("-source", "1.8", "-target", "1.8")
libraryDependencies += "org.apache.spark" % "spark-core_2.11" % "2.4.3" % "provided"
mainClass in Compile := Some("WordCount")
这里的version我写的是1.0,之后修改WordCount之后,可以相应的改成2.0,3.0之类的。
JavaOption,要填写当前电脑安装的Java版本。
ScalaVersion填写scala的Version
对于libraryDependencies。spark-core后面的数字是这样决定的:
首先进入spark主目录中的jars目录下:
cd jars
然后输入如下内容:
ls * | grep "core"
然后再输出中找到scala-score,后面的2.11和2.4.3都是根据这个来填的:
接着输入如下命令build:
sbt package
成功后,输入ls应该能看到当前目录下多了project和target两个文件夹
进入target/scala-2.10文件夹
cd target/scala-2.10/
可看到如下:
将这里的sparkscala_2.10-1.0.jar复制到spark的主目录下:
cp sparkscala_2.10-1.0.jar ~/spark-2.4.3-bin-hadoop2.7
下一步,把数据存在HDFS上。
回到hadoop主目录,然后输入如下命令在hdfs创建文件夹input:
cd ~/hadoop-2.9.2
bin/hdfs dfs -mkdir /input
然后我把本地存的一个文本文档“beauty_and_beast.txt”放进了文件夹,然后回到spark目录:
bin/hdfs dfs -put beauty_and_beast.txt /input
cd ~/spark-2.4.3-bin-hadoop2.7/
此时输入如下命令,就能在spark上运行刚刚编写的WordCount程序了:
bin/spark-submit --class WordCount --master spark://falcon-1:7077 sparkscala_2.10-1.0.jar hdfs://falcon-1:9000/input
此时运行的log会在控制台输出,并且程序结果也会打印在控制台。
(四)wordcount cluster运行模式
例子上是默认的client模式,这个例子是cluster模式。运行命令行模式就是在最后submit的命令中加上“--deploy-mode cluster”。
两个模式都运行在cluster上,数据也都是从hdfs读取的。
区别在于,每个job的driver在哪里,如果是client模式的话,driver就在提交job的node上。
如果是cluster模式的话,driver可能在任意一台cluster中的node上。
相应的,driver中的log输出一点也会不同。用client模式提交,log直接打印到控制台,方便debug。
而对于cluster模式,log是放在了spark主目录中work文件夹中。
——————————————————————————————————————————————————
废话不多说,直接上例子。
打开spark_test中的WordCount.scala修改代码:
cd ~/spark-2.4.3-bin-hadoop2.7/spark_test
vim WordCount.scala
改成如下内容:
import org.apache.spark.SparkContext
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext._
import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.FileSystem
object WordCount{
def main(args : Array[String]) {
val hadoopconf = new Configuration();
hadoopconf.setBoolean("fs.hdfs.impl.disable.cache", true);
val fileSystem = FileSystem.get(hadoopconf);
//spark configuration
val conf = new SparkConf().setAppName("WordCount");
val sc = new SparkContext(conf);
val wordcount=sc.textFile(args(0)).flatMap(_.split(" ")).map(word=>(word,1)).reduceByKey(_+_).saveAsTextFile(args(1));
println("Word Count program running results are successfully saved.");
}
}
下一步修改build.sbt文件:
vim build.sbt
把其中的version从1.0改成2.0:
name := "sparkScala"
version := "2.0"
scalaVersion := "2.10.4"
javacOptions ++= Seq("-source", "1.8", "-target", "1.8")
libraryDependencies += "org.apache.spark" % "spark-core_2.11" % "2.4.3" % "provided"
mainClass in Compile := Some("WordCount")
然后打包代码:
sbt package
将最后的jar包复制到spark主目录下,注意此时复制的是2.0版本的jar包:
cp target/scala-2.10/sparkscala_2.10-2.0.jar ~/spark-2.4.3-bin-hadoop2.7
值得注意的是,在这里需要把jar包复制到所有的node中,不然在运行时会出现找不到jar包的错误:
cd ~/spark-2.4.3-bin-hadoop2.7
scp -r sparkscala_2.10-2.0.jar falcon-2:/home/qianwen/spark-2.4.3-bin-hadoop2.7/sparkscala_2.10-2.0.jar
scp -r sparkscala_2.10-2.0.jar falcon-3:/home/qianwen/spark-2.4.3-bin-hadoop2.7/sparkscala_2.10-2.0.jar
scp -r sparkscala_2.10-2.0.jar falcon-4:/home/qianwen/spark-2.4.3-bin-hadoop2.7/sparkscala_2.10-2.0.jar
scp -r sparkscala_2.10-2.0.jar cat-2:/home/qianwen/spark-2.4.3-bin-hadoop2.7/sparkscala_2.10-2.0.jar
scp -r sparkscala_2.10-2.0.jar cat-4:/home/qianwen/spark-2.4.3-bin-hadoop2.7/sparkscala_2.10-2.0.jar
接着就可以提交任务了:
bin/spark-submit --class WordCount --master yarn-cluster sparkscala_2.10-2.0.jar hdfs://falcon-1:9000/input hdfs://falcon-1:9000/output
注意看此时的命令行和之前的区别:
- 添加了"--deploy-mode cluster" ,把运行模式改成了cluster
- 还添加了输出文档地址。这是因为在这一次的wordcount代码中,我把最终结果saveAsTextFile了,并且地址设为“args(1)”。
这一次的运行输出非常简洁:
值得注意的是,不管运行是成功还是失败,运行输出都会只有这么少。具体的结果要去运行driver的node看log才能知道。所以cluster模式不适合用来做debug!!!
在我的cluster里,运行该例子的node是falcon-3,在falcon-3的work文件夹中,有driver信息。
进入该文件夹,输出stdout和stderr,就能看到程序是否运行成功:
可以看到我的例子已经运行成功了。所以现在在master node上的hdfs中,应该可以看到输出结果:
cd ~/hadoop-2.9.2/
bin/hdfs dfs -ls /output
输入如下命令查看结果:
bin/hdfs dfs -cat /output/part-00000
参考资料
https://www.jianshu.com/p/65a3476757a5 (这篇对于spark运行模式解释非常详细)
https://www.cnblogs.com/kwongtai/p/7226412.html
https://www.jianshu.com/p/5a46a3193ca0
http://wuchong.me/blog/2015/04/04/spark-on-yarn-cluster-deploy/
https://www.ibm.com/developerworks/cn/opensource/os-cn-spark-deploy1/index.html
http://www.voidcn.com/article/p-hbcbpcep-bpv.html
《spark快速大数据分析》