JVM 是必须的,所以需要 Java(JDK 1.8+), 想写 Python 的还需要 Python(2.7.x/3.x).
快速试用或简单尝试的,可以考虑 databrick cloud 或者本地安装 spark-notebook/spark-notebook 可以在浏览器中写 Scala 代码体验一些 Spark 和 Scala 的特性。
对于 Spark 的安装,去官方页面下载选中的编译好压缩包即可,解压即用。其中 1.x(1.6.3) 在一些老的集群中还在大量使用,但基本不再有新的功能加入。2.x(2018 年 2 月底 2.3.0 引入了大量新的 feature) 开发非常活跃,API 的便利性和性能都有较大提升,推荐使用。基于 Spark 的开发模式往往比较重,如果使用 IDE 的话推荐使用 IntelliJ IDEA 进行开发,安装好 Scala 和 Python 插件。
Windows
Windows 下使用 Spark 需要做的准备工作稍微多一点点,设置 Spark 环境 SPARK_HOME
为 Spark 解压目录 D:\spark\spark-1.6.3-bin-hadoop2.6
. 尽管 Spark 在本地运行并不需要完整的 Hadoop 环境,但还是间接依赖了一些 Hadoop 提供的文件操作工具,故在 Windows 下需要一些 POSIX 的文件权限操作,因此我们需要 winutils.exe
. 作者在 steveloughran/winutils 上放出了预编译好的二进制版本,按需选择即可。需要注意的是 winutils.exe
需要置于 HADOOP_HOME
的 bin
目录下,我们可以新建 D:\hadoop
作为 HADOOP_HOME
变量。变量设置好后需要判断这两个环境变量是否生效。
PySpark
使用 PySpark 时最重要的环境变量是 PYTHONPATH
和 spark-submit
提交时 --py-files
Python 及其依赖的打包注意事项。
#!/usr/bin/env bash
set -e
export SPARK_HOME=${SPARK_HOME:="/usr/hdp/2.6.1.0-129"}
export PYTHONPATH=$SPARK_HOME/python:$SPARK_HOME/python/lib/py4j-0.9-src.zip:$SPARK_HOME/python/lib/pyspark.zip:$PYTHONPATH
export SPARK_MASTER=${SPARK_MASTER:="local[*]"}
spark-submit \
--master \
${SPARK_MASTER} \
--deploy-mode \
client \
--name \
PySpark \
--verbose \
main.py $@
Scala
使用 Scala 来开发 Spark 程序是最为 native 的方式,也没有性能惩罚,是我个人最喜欢的方式。考虑到我们通常并不将 Spark 的核心包打包至最终的 jar 包提交,我们可以在 build.sbt
中指定 Spark 相关依赖为 provided
, 完整的 build.sbt
见下文。
name := "scala-ml-text"
organization := "com.yintech"
version := "1.0"
scalaVersion := "2.10.7"
val sparkVersion = "1.6.3"
lazy val sparkDependencies = Seq(
"org.apache.spark" %% "spark-core" % sparkVersion,
"org.apache.spark" %% "spark-mllib" % sparkVersion,
"org.apache.spark" %% "spark-hive" % sparkVersion
)
libraryDependencies ++= Seq(
"log4j" % "log4j" % "1.2.17",
"org.slf4j" % "slf4j-log4j12" % "1.7.10",
"com.typesafe" % "config" % "1.2.1",
"com.databricks" % "spark-csv_2.10" % "1.5.0"
)
libraryDependencies ++= sparkDependencies.map(_ % "provided")
assemblyMergeStrategy in assembly := {
case PathList("META-INF", xs @ _*) => MergeStrategy.discard
case x => MergeStrategy.first
}