赞
踩
使用Scala编写的程序需要使用sbt进行编译打包,相应的,java程序使用Maven编译打包,而Python程序通过spark-submit直接提交。
由于spark中并没有自带sbt,因此我们需要下载安装一个
安装sbt的方法参考上述内容
目录
在https://www.scala-sbt.org/download.html 网站上下载sbt 1.3.8
下载好以后,使用共享文件夹,让虚拟机能访问到该文件
》cd /usr/local
将下载好的sbt安装包拷贝到/usr/local文件夹中
》sudo cp /mnt/hgfs/ubuntu-share/sbt-1.3.8.tgz .
在此处解压缩
》sudo tar -zxvf ./sbt-1.3.8.tgz
为文件夹赋予权限,此处的zhuluobigdata是本台计算机的用户名
》sudo chown -R zhuluobigdata /usr/local/sbt
接下来将bin目录下的sbt-launch.jar复制到sbt的安装目录下
》cd sbt
》sudo cp ./bin/sbt-launch.jar ./
接下来在安装目录中,使用下面的命令创建一个Shell脚本文件,用于启动sbt
》sudo vim /usr/local/sbt/sbt
将如下内容写入:
#!/bin/bash
SBT_OPTS="-Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256M"
java $SBT_OPTS -jar `dirname $0`/sbt-launch.jar "$@"
保存以后,需要为该文件添加一个可执行权限
》sudo chmod u+x /usr/local/sbt/sbt
接下来可以查看一下版本信息:
》sudo ./sbt sbtVersion
(访问sbt版本时,sbt将通过访问国外网站下载需要的内容,所以如果没有开代理的话,可能会出现卡住的情况,建议开启梯子后执行此步)
此时发生报错:
/sbt: line 3: java: command not found
搜索一下原因:
可以这样子排错:
首先,可能是jdk环境变量的问题
如果已经安装了jdk并配置过环境变量,重新执行
》source /etc/profile
重新使配置文件生效,再执行看看是否能够成功
若还是不能成功,则有可能是因为在sudo环境下,系统的环境变量发生了变化,导致找不到java命令
可以执行:
》sudo env “PATH=$PATH” ./sbt sbtVersion
这个命令会将PATH环境变量在sudo环境下重新设置为当前用户的PATH环境变量,从而解决找不到Java命令的问题
如果能返回上述信息,则说明sbt已经安装成功了
但是这个过程非常的漫长,会花费很长的时间
要下载不少内容
(为了减少时间,可以参考后续的内容:更换仓库地址加快编译速度)
但是,只要安装成功,第二次开始运行sudo env "PATH=$PATH" ./sbt sbtVersion或者执行编译打包命令,速度就会变得比较快了。
大概过了十多分钟,输出了如下结果
》sudo env "PATH=$PATH" ./sbt sbtVersion
第二次执行,查看版本,展示出如下结果仅花费4,5秒的时间
关于如何更换仓库地址,加快编译速度
在此不过多赘述,感兴趣的hxd可以查看厦门大学林子雨老师的博客:
网站中有换源的步骤以及老师的个人思考
在终端中执行如下命令创建一个文件夹sparkapp作为应用程序的根目录。
Mycode目录是专门用来保存我们的代码的
一定要按照这个规定定义目录
在此,我在用户主文件夹下,创建我的目录
》cd ~
》mkdir ./sparkapp
》mkdir -p ./sparkapp/src/main/scala
以上命令将在用户主文件夹下创建一个sparkapp文件夹,作为应用程序根目录
在~/sparkapp/src/main/scala目录下创建一个新的文件:SimpleApp.scala
》cd sparkapp/src/main/scala
》vim SimpleApp.scala
写入如下的内容:
接下来需要去添加sbt文件用于编译
在~/sparkapp目录下创建文件simple.sbt
》cd ~/sparkapp
》vim simple.sbt
添加内容如下,声明该独立应用程序的信息以及与Spark的依赖关系
Name和version声明了项目的名称和版本信息
另外两个字段需要根据我们的版本进行选择,在spark shell启动的时候,有如下信息:
此输出告诉我们,spark的版本为2.4.5,scala的版本为2.11.12
因此,上面的.sbt配置文件中与版本有关的信息要进行针对性的修改。
目前我们只使用到了spark-core这个核心包
后续如果要使用流计算、图计算、机器学习等内容,还需要引入其他的包
为了保证sbt能够正常运行,我们需要检查整个应用程序的文件结构:
》cd ~/sparkapp
》find .
输出的文件结构应该如下图所示:
接着,可以将整个应用程序进行打包
》sudo /usr/local/sbt/sbt package
出现如上的提示,这表明sbt获取不到java的环境
像先前查看sbt版本遇到的问题一样,我们使配置文件/etc/profile重新生效
》source /etc/profile
再次执行仍然还是command not found
原因也和先前查看sbt版本遇到的问题一样,在sudo的权限下,系统的环境变量发生了变化,导致找不到java命令
因此,我们将指令修改为,即可成功启动编译
》sudo env "PATH=$PATH" /usr/local/sbt/sbt package
第一次编译需要下载不少依赖,因此,最好开启梯子再进行此步
编译成功的返回如下:
在我们的应用程序目录下,就会多生成project文件夹和target文件夹
进入./target/scala-2.11文件夹,可以看到打包好的jar包
现在已经获取到了jar包,我们可以将其提交并运行。
可以通过spark-submit提交应用程序,该命令的格式如下:
将生成的jar包通过spark-submit提交到Spark中运行,命令如下:
》/usr/local/spark-2.4.5-bin-hadoop2.7/bin/spark-submit --class "SimpleApp" ~/sparkapp/target/scala-2.11/simple-project_2.11-1.0.jar
这样会输出非常多的执行信息,在诸多信息中,可以找到我们程序要产生的结果
可以使用下面的指令,直接查看我们希望看到的输出
》/usr/local/spark-2.4.5-bin-hadoop2.7/bin/spark-submit --class "SimpleApp" ~/sparkapp/target/scala-2.11/simple-project_2.11-1.0.jar 2>&1 | grep "Lines with a:"
这样就可以把我们希望看到的输出筛选出来了
① 在Spark Shell中执行词频统计
先创建一个word.txt文件用于词频统计
》cd /usr/local/spark-2.4.5-bin-hadoop2.7/
》sudo mkdir mycode
》cd mycode
》sudo mkdir wordcount
》cd wordcount
》sudo vim word.txt
将以下内容写入word.txt用于词频统计
I woke up feeling a sense of purpose. It was a beautiful day outside, with the sun shining and a gentle breeze blowing. I decided to go for a walk in the park, where I could enjoy the natural beauty around me. As I strolled along the path, I noticed the colorful flowers blooming in the flowerbeds, and the trees swaying in the wind.
I continued my walk, enjoying the fresh air and the peaceful atmosphere. Suddenly, I heard a loud noise coming from behind a nearby building. Curiosity getting the better of me, I decided to investigate. As I got closer, I realized it was a group of children playing with a ball. They were having so much fun, laughing and joking.
接下来打开spark-shell,执行词频统计相关代码
》val textFile = sc.textFile("file:///usr/local/spark-2.4.5-bin-hadoop2.7/mycode/wordcount/word.txt")
解释:在sparkshell中自带了sc对象(Spark Context),使用该对象可以读取本地文件系统或者HDFS分布式文件系统中的文件。在此我们访问本地文件
返回内容表明,现在的textFile变量已经是一个RDD了
》val wordCount = textFile.flatMap(line=>line.split(" ")).map(word=>(word,1)).reduceByKey((a,b)=>a+b)
解释:对textFile这个RDD进行粗粒度的转换处理。
首先,对于textFile中的每一行,都以空格” ”为分界线,将单词区分开
其次,对于每个单次,都将其以(单词,1)的方式写入map中
最后,key值相同的项进行合并,他们的数量相加
产生的结果为新的RDD
》wordCount.collect()
解释:对wordCount对象使用collect()方法,能将集群中所有节点的处理结果获取并整合
》wordCount.foreach(println)
解释:即打印当前的统计结果
②编写独立应用程序执行词频统计
基于前面创建的~/sparkapp程序目录
在~/sparkapp/src/main/scala目录下创建新的.scala文件
》vim WordCount.scala
输入如下的内容
这段代码的解释为:
首先,导入了SparkContext、SparkConf 以及 SparkContext 对象中的一些函数
定义了名为WordCount的对象,在其中编写了主函数main()
变量inputFile包含要统计词频的文本文件的本地路径
创建了一个名为conf的SparkConfig对象,并设置了应用程序名称和运行模式
这里的local[2]表示使用两个本地的线程来执行
基于SparkConfig对象,创建了一个名为sc的SparkContext对象
利用SparkContext对象中的textFile()函数,读取了包含文本内容的文件,并将其转换为RDD对象。
利用flatMap()函数,将所有单词拆分成一个个字符串,并将它们转化为键值对形式
其中键是单词,值为数字1
最后利用reduceByKey函数,按照键值对中的键将所有单词进行分组,并将每个单词出现的次数相加。最后通过collect()函数将结果返回到本地驱动程序并打印结果。
使用sbt进行编译,生成jar包
》sudo env "PATH=$PATH" /usr/local/sbt/sbt package
使用spark-submit提交运行
》/usr/local/spark-2.4.5-bin-hadoop2.7/bin/spark-submit --class "WordCount" ~/sparkapp/target/scala-2.11/simple-project_2.11-1.0.jar
上面这个命令和之前相比,只在类名处有变化
因为程序执行需要从mian入手,而我在sparkapp应用程序目录中写入了两个以上的main,因此一定要指定入口类的名字,让程序能够正常地执行。
上图为执行成功之后的部分输出内容。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。