Saprk 监控
目前掌握了
作业运行中的监控,4040。
运行结束的HistoryServer,18080。也可以根据Api自己开发。
作业运行中的监控也可以有API自己开发。
SparkListener
继承SparkListenerInterface,实现作业开始前、后等需要做的操作。
直接实现SparkListener,覆写需要的方法就可以。
override def onTaskEnd(taskEnd: SparkListenerTaskEnd): Unit = {
val metrics = taskEnd.taskMetrics //通过metrics可以拿到很多信息
val taskMetricsMap = scala.collection.mutable.HashMap(
"executorDeserializeTime" -> metrics.executorDeserializeTime, //executor的反序列化时间
"executorDeserializeCpuTime" -> metrics.executorDeserializeCpuTime, //executor的反序列化的 cpu时间
"executorRunTime" -> metrics.executorRunTime, //executoor的运行时间
"resultSize" -> metrics.resultSize, //结果集大小
"jvmGCTime" -> metrics.jvmGCTime,
"resultSerializationTime" -> metrics.resultSerializationTime,
"memoryBytesSpilled" -> metrics.memoryBytesSpilled,
"diskBytesSpilled" -> metrics.diskBytesSpilled,
"peakExecutionMemory" -> metrics.peakExecutionMemory //executor的最大内存
)
// ....
}
然后在SparkConf中set自定义的SparkListener监听器。
new SparkConf().set("spark.extraListeners","com.gargantua.listener.MySparkListener")
在配置文件中指定的话,对所有作业都监听。
jmx
http://gargantua:9870/jmx 可以拿到hdfs的json格式的运行信息
同理,yarn的json也可以获取http://gargantua:8123/jmx
于是可以带参数的http请求查询指定的信息
http://gargantua:9870/jmx?qry=…
可以定时调度去获取信息,再记录到DB,在由UI展示、邮件或短信电话告警
Spark on Yarn
MR、Spark、Flink on Yarn 都是因为有实现了对应的ApplicationMaster才能跑作业
MRAM、SparkAM、FlinkAM
确保HADOOP_CONF_DIR指向hadoop集群
不然会报错的
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
Spark on Yarn 可以 client提交yarn,可以spark集群提交yarn
client提交yarn
spark-shell 可以直接在本地启动,也可以提交jar到yarn,也可以on Yarn 启动。
spark-shell \
--master yarn \
--deploy-mode client \
--class org.apache.spark.examples.SparkPi \
/home/hadoop/app/spark-3.2.0-bin-hadoop3.2/examples/jars/spark-examples*.jar \
10
scala>
client提交yarn后有如下进程
12039 SparkSubmit // spark-shell driver
12231 ExecutorLauncher // 其实就是ApplicationMaster,只为区分 cluster-mode还是 client-mode
12298 YarnCoarseGrainedExecutorBackend // executer
12330 YarnCoarseGrainedExecutorBackend // executer
cluster提交yarn
不能再用spark-shell,spark集群只需要提交就行,没有、没法打开终端
spark-submit \
--master yarn \
--deploy-mode cluster \
--class org.apache.spark.examples.SparkPi \
/home/hadoop/app/spark-3.2.0-bin-hadoop3.2/examples/jars/spark-examples*.jar \
10
提交后有如下进程
16185 SparkSubmit
16323 ApplicationMaster
16488 YarnCoarseGrainedExecutorBackend
16539 YarnCoarseGrainedExecutorBackend
区别总结
client
driver是运行在提交的机器的 + 调度、分发作业(本机终端不能退出,不然driver和所有的executor关系就断了)
AM: 从YARN上申请资源
pi:在driver端是看的到日志输出的
cluster
driver是运行在am里面的(毕竟现在集群下有多个spark,总不能让driver是运行在每个提交的机器)
AM: 从YARN上申请资源 + 调度、分发作业
pi:日志在终端上是看不到的,你的去container里面找
对于client模式来说,提交的机器可以是集群外的。
在这个条件下才有一个说法,少用client模式,因为driver与executer的交互网络开销会非常大。对于提交机器是属于集群内一台机器而言,cluster模式和client模式区别不大。
cluster模式下,driver与executer仍然避免不了网络交互,只不过都在一个集群内(局域网内、同机架内)。
其实区别不大,但生产还是推荐cluster模式;自测可以client,方便查日志。
ps -ef | grep [pid]
僵尸进程就把他父进程也杀掉,父进程的pid在他pid的后面。
spark-shell与spark-submit
spark-submit
主要是用于提交编译并打包好的Jar包到集群环境中来运行,和hadoop中的hadoop jar命令很类似,hadoop jar是提交一个MR-task,而spark-submit是提交一个spark任务。
相对于spark-shell来讲它不具有REPL(交互式的编程环境),在运行前需要指定应用的启动类,jar包路径、参数等内容。可以设置不同的Spark所支持的集群管理和部署模式。
spark-shell
这个命令启动一个可给用户输入spark命令的shell,是一个REPL环境。指定master时通过spark-submit提交作业,不指定master时会启动一个SparkSubmit进程来模拟Spark运行环境。
通过查看spark-shell源码可以发现在主main中他会调用spark-submit 的类的入口。运行spark-shell提交任务后最终还是由spark-submit来完成。