首玩ide的老年选手, 记录一下不然几天就忘.
目标: mac osx + spark1.3.0 + scala 2.10.6 + intellij idea 15. 能够在本地ide开发, 本地local模式测试, 打包扔到集群上跑. 希望scala和sbt装在本机全局可用, 不止用于这一个项目.
{命令行大法在往后翻, 在分割线之后}
安装intellij idea.
官网下载, 按提示下一步到底. 安装推荐的那个scala插件.安装sbt.
想在本机装一个独立的sbt, 各个项目都能用, 而不是每次需要用到sbt的时候去ivy仓库荡.
按官网指导走: brew install sbt 装最新版0.13.9.
安完之后敲一下sbt, 会花20分钟下载一些它自己需要用的包, 没vpn就先睡一觉.安装scala
想在本机装一个独立的scala, 没事儿还能写几句玩玩. 以后编译打包都用本机装的这个, 而不是去仓库找.
按官网指导走: 下载压缩包解压, 再配置两个环境变量, 即$SCALA_HOME以及给$PATH加上$SCALA_HOME/bin
版本不要太新, 2.10就好. 如果版本太高(2.11)还得自己编译spark包, 因为编译好的spark包没支持scala2.11.先把scala+sbt配置好. 下一步再搞spark.
new project的时候选scala->sbt.
项目一新建, 底部进度条就开始下载各种东西了, 点红X停止下载.做这几个设置:
- 先在preference里面搜sbt, 把调用的launcher由云端bundled改成刚才自己安装好的. 路径大概在/usr/local/Cellar/sbt/xxx 让ide用本地的sbt, 别去云端乱荡瞎折腾.
- 把build.properties里面的sbt的version改成刚才安装的那个, 不然它还去云端荡.
- build.sbt里写了引用的scala版本. 改成自己安装的版本, 再写一句这个让它引用本地的包
:scalaHome := Some(file("/usr/local/share/scala-xxx"))
就是填上$SCALA_HOME. - 在项目的libraries里面加上scala的sdk(就是自己安装的那个路径)
刷新一下项目. 写个scala的hello world, 点一下运行, 应该就行了.
sbt打个包试试: 在project_dir起个sbt shell ->clean
->run
一下ok ->package
. 就打好jar包了.
检查运行一下这个jar包: 进到放打好的jar包的目录,
java -cp .:$SCALA_HOME/lib/scala-library.jar:ScalaTest.jar ScalaTest
要是用java -jar跑得用-Xbootclasspath/a加scala的包的cp搞spark包
之前的已经搞定了scala语言和sbt打包工具. 现在只需考虑spark相关就行了.
找到集群跑的spark assembly jar包. 想在集群跑什么版本的, 这里就用什么版本, 保持一致嘛.
把spark-assembly-xxx.jar加到project的libraries里面, 供ide折腾用.
同时把此包加到build.sbt里, 让sbt打包的时候知道去哪儿找, 别迷茫或者跑去云端下载.
unmanagedJars in Compile += file("spark-assembly-xxx.jar")
刷新一下项目, External Lib里面的sbt-unmanaged里面应该会多这个spark包.
写一个测试的spark程序, setMaster(“local”), 就能run了.sbt打包: 在project_dir起个sbt shell ->
clean
->run
but fail… ->package
anyway, 就打成一个jar包. 包里没有spark的依赖, 也没有scala的依赖, 因为其实扔集群上跑其实应该并不需要包进去.
扔集群, spark-submit试一下, 成功.
//好些个细节没搞太清楚, 待研究. 好多关于sbt plugin以及add dependency的资料, 表示没看懂并且好像并不太需要…
进一步地, 发现其实我的需求其实可能并没有这么复杂.
新目标: 并懒得装ide, 只想写个spark的scala脚本, 本地测一下语法, 打包能扔集群上跑就行了.
推倒重来, 换一台机器, 找个服务器吧.
准备工作.
- 需要一个scala. 由于服务器权限问题, 可能没那么方便安装全局可用的. 所以安一个自己可用的就行了. 老方法, 下载解压, 然后配置那两个环境变量.
- 找到集群跑的spark-assembly包, 放到某个位置.
理一下思路.
其实我们需要三个功能(工具): 编译; 本地运行测试; 打包.编译
建一个project目录, 写个测试的SparkTest.scala
(注意)在$PROJECT_DIR下, 这么编译:
rm -rf compiled
mkdir compiled
scalac -classpath /xxx/spark-assembly-1.3.0-hadoop2.4.0.jar -d compiled/ SparkTest.scala
这样就把class编译好放在compiled目录下了.本地运行测试
代码里setMater("local")
(注意)在$PROJECT_DIR下,
java -cp /xxx/spark-assembly-1.3.0-hadoop2.4.0.jar:.:compiled com.xxx.xxx.SparkTest
打包
rm -rf SparkTest.jar
echo "Main-Class: com.xxx.xxx.SparkTest" > manifest.mf
jar cvfm SparkTest.jar manifest.mf -C compiled .
rm manifest.mf
就打包好了, jar就放在$PROJECT_DIR了spark-submit测一下三种master(注意跟代码里的master不能冲突), 都ok. all done
附
1. 刚才有个sbt>run
-> fail. 大概就是说, 用scala运行spark的class文件会有akka相关的错误, 但是用java运行就ok. 这是因为, scala自带了一个akka库, 写在bootcp里面了, 会优先调用自带的akka, 但是跟spark的akka不兼容.