Spark集群及IDEA远程运行
Local模式
单节点完成全部工作,一般用于调试、演示等,优点是方便,缺点是单机性能有限
解压Spark并配置环境变量即可使用(WIndows环境下还需要相应版本的winutils)
spark-shell启动本地模式
Standalone模式
Spark自身的主从模式,集群规划如下
centos1 | centos2 | centos3 |
---|---|---|
Master | ||
Worker | Worker | Worker |
-
修改配置文件workers(旧版本为slaves)
centos1 centos2 centos3
-
修改spark-env.sh
SPARK_MASTER_HOST=centos1 SPARK_MASTER_PORT=7077
-
分发配置文件目录
-
启动集群,在master节点
${SPARK_HOME}/sbin/start-all.sh
高可用
高可用基于zookeeper,无需配置master节点,哪个节点先启动master极为master节点,后续启动的master作为备用
-
修改配置文件spark-env.sh
#Master 监控页面默认访问端口为 8080,但是可能会和 Zookeeper 冲突,所以改成 8989,也可以自 定义,访问 UI 监控页面时请注意 SPARK_MASTER_WEBUI_PORT=8989 export SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=centos1:2181,centos2:2181,centos3:2181"
-
在centos1启动集群
${SPARK_HOME}/sbin/start-all.sh
-
在其他节点启动master
${SPARK_HOME}/sbin/start-master.sh
-
查看节点状态
http://{host}:8989
centos1为ALIVE,其他节点为STANDBY
-
验证高可用
kill掉centos1的master,一段时间后某一节点master转为ALIVE状态
YANR集群
以yarn作为资源调度框架配置反而是最简单的
- 配置hdfs和yarn配置文件目录
...
# spark-env.sh
HADOOP_CONF_DIR=${HADOOP_HOME}/etc/hadoop
- 启动HDFS集群和YARN集群
- 启动Spark集群
配置历史服务
-
修改spark-defaults.conf
spark.eventLog.enabled true spark.eventLog.dir hdfs://centos1:8020/spark-log spark.yarn.historyServer.address=centos1:18080 spark.history.ui.port=18080
-
在HDFS创建目录
hdfs dfs -mkdir /spark-log
-
添加日志配置
SPARK_HISTORY_OPTS="-Dspark.history.ui.port=18080 -Dspark.history.fs.logDirectory=hdfs://centos1:8020/spark-log -Dspark.history.retainedApplications=30"
IDEA Spark开发
-
本地模式
即local模式,在windows上配置spark环境即可,直接IDEA运行
object SparkTest {
def main(args: Array[String]): Unit = {
val spark: SparkSession = SparkSession.builder
.master("local[*]")
// .master("spark://192.168.8.3:7077")
// .config("spark.driver.host", "192.168.8.1")
// .config("spark.driver.port", "9999")
.appName("sparkTest").getOrCreate
val numDS: Dataset[lang.Long] = spark.range(5, 100, 5)
numDS.show(5)
spark.close()
}
}
这样调试运行是最方便的,但是无法利用服务器资源,只能跑简单一点的任务
-
Driver与集群通信
如果直接连接spark://master:7077,代码能正常运行,但是一直卡住,不断分配移除Executor。在这种模式下,IDEA扮演的是Driver的角色,与集群通信,部署任务,一直卡住的原因是虚拟机与主机不能正常通信,开放虚拟机ip的防火墙,并显示指定Driver的ip和端口(不然动态变化)后可正常执行任务。
object SparkTest {
def main(args: Array[String]): Unit = {
val spark: SparkSession = SparkSession.builder
// .master("local[*]")
.master("spark://192.168.8.3:7077")
.config("spark.driver.host", "192.168.8.1")
.config("spark.driver.port", "9999")
.appName("sparkTest").getOrCreate
val numDS: Dataset[lang.Long] = spark.range(5, 100, 5)
numDS.show(5)
spark.close()
}
}
这样运行调都比较方便,是一个很好的选择
-
IDEA + spark-submit
-
项目打成jar包
File -> ProjectStruct -> Artifact -> jar(from dependencies…)
IDEA打包默认会对jar包进行sign操作,java执行jar包会报找不到主类的错误,有两个解决方案
- 不打成一个jar包,多个jar包和项目类,即选择copy to the output directory and link via manifest,上传到
- 只打包项目类,remove掉所有Extract的依赖
具体可以参考这篇文章
-
spark-submit
Run/Debug Configuration -> 添加spark-submit -> ssh
可以配置spark-submit相关参数
- Application: 选择idea刚配置的jar包
- Class: 启动类
- 选择Add Options -> Dependencies可指定-jars参数,其他参数类似
- Add Options -> SFTP Options可指定上传目录
配置完成后,生成的命令如下
/opt/spark3.0/bin/spark-submit --verbose --master spark://centos1:7077 --deploy-mode client --class com.windcf.SparkTest --name spark-test --jars file:///root/spark-test/dm-jdbc-jre1.8.jar /root/spark-test/spark-learn.jar
提前在虚拟机创建spark-test目录
-
执行
object SparkTest { def main(args: Array[String]): Unit = { val spark: SparkSession = SparkSession.builder // .master("local[*]") // .master("spark://192.168.8.3:7077") // .config("spark.driver.host", "192.168.8.1") // .config("spark.driver.port", "9999") .appName("sparkTest").getOrCreate val numDS: Dataset[lang.Long] = spark.range(5, 100, 5) numDS.show(5) numDS.write.csv("file:spark-test") spark.close() } }
这种方式Driver也在集群了,和生产环境执行任务已经没有太大区别了
-