让 Spark Streaming 程序在 YARN 集群上长时间运行(三)—— Grafana、优雅地停止(Graceful stop)、总结

前段时间看到了外国朋友写的一篇文章,觉得还不错,于是就把他翻译一下,供大家参考和学习。
如果没看过前两篇文章第一篇第二篇),建议先去看一下哈,这里是接着上两篇文章来写的哈~

Grafana

当你为 Spark 应用程序配置第一个 Grafana 仪表板时,首先出现的问题是:

How to configure Graphite query when metrics for every Spark application run are reported under its own application id?(注:不好意思,这句不知怎么翻译)

如果你足够幸运并且勇于使用Spark 2.1,请将应用程序的 metric 固定为静态的应用程序名称:

--conf spark.metrics.namespace=my_application_name

对于2.1以上的Spark版本,需要使用Graphite内置函数的一些用法。

Driver metrics 使用通配符 .*(application_[0-9]+).*aliasSub Graphite 的函数将 “application id” 显示为图例:

aliasSub(stats.analytics.$job_name.*.prod.$dc.*.driver.jvm.heap.used, ".*(application_[0-9]+).*", "heap: \1")

对于 executor metrics,再次使用.*(application_[0-9]+).*aliasSub 函数来对所有 Spark executor 的 metric 值进行求和,最后使用aliasSub函数将“application id”作为图例表示:

aliasSub(groupByNode(stats.analytics.$job_name.*.prod.$dc.*.[0-9]*.jvm.heap.used, 6, "sumSeries"), "(.*)", "heap: \1")

最后,Spark Job 的 Grafana 仪表板大致如下所示:
这里写图片描述

如果经常重新启动 Spark 应用程序,则应该从 Graphite 中删除旧的已完成运行的 metrics。 由于 Graphite 没有合并不活动的 metrics,因此旧 metrics 会减慢Graphite 本身和 Grafana 查询的速度。


优雅地停止

最后一个难题是如何以一种优雅的方式停止在 Yarn 上部署的 SparkStreaming 程序。停止(或杀死)YARN 应用程序的标准方法是使用yarn application -kill [applicationId]命令。这个命令能停止我们的程序,但是程序有可能在小批处理的过程中。因此,如果 job 读取 Kafka 的数据,将处理结果保存在 HDFS 上,并最终提交 Kafka 偏移量,那么当作业在提交偏移量之前停止时,应该将该批次的数据保存在 HDFS中(注:receiver的方式)。

解决正常停止问题的第一个尝试是 在 shutdown hook(关闭钩子)中调用 SparkStreaming context 的停止方法。

sys.addShutdownHook {
    streamingContext.stop(stopSparkContext = true, stopGracefully = true)
}

令人失望的是,shutdown hook(关闭挂钩)被调用得太晚以至于无法完成已经开始的一小批的处理,并且Spark应用程序几乎立即被杀死。 而且,根本不能保证关闭钩子会被JVM调用。

在编写本博文时,优雅地关闭 YARN 上的 Spark Streaming 应用程序的唯一确认方式是 以某种方式通知关于打算停止的 application,然后以编程的方式停止 streaming context(但不是关闭挂接的方式)。 如果通知的 application 在定义的时间后仍然没有停止,那么可以调用命令yarn application -kill作为最后的手段。

应用程序可以在 HDFS 上使用标记文件(最简单的方法),或者使用在 Driver上公开的简单的socket/http端点(复杂的方式)通知 application。

因为我喜欢KISS原则,所以在下面就是使用标记文件来启动/停止 Spark Streaming 应用程序的 shell 脚本伪代码:

start() {
    hdfs dfs -touchz /path/to/marker/my_job_unique_name
    spark-submit ...
}

stop() {
    hdfs dfs -rm /path/to/marker/my_job_unique_name
    force_kill=true
    application_id=$(yarn application -list | grep -oe "application_[0-9]*_[0-9]*"`)
    for i in `seq 1 10`; do
        application_status=$(yarn application -status ${application_id} | grep "State : \(RUNNING\|ACCEPTED\)")
        if [ -n "$application_status" ]; then
            sleep 60s
        else
            force_kill=false
            break
        fi
    done
    $force_kill && yarn application -kill ${application_id}
}

在 Spark Streaming 应用程序中,后台线程应监视标记文件,并在文件消失时调用 context 的 stop 方法

streamingContext.stop(stopSparkContext = true, stopGracefully = true)

总结

如你所见,部署在 YARN 上的关键任务 Spark Streaming 应用程序的配置非常复杂。 这是由一些非常聪明的开发者经过漫长而乏味的迭代过程总结出来的。 但最后,长期运行的 Spark Streaming 应用程序非常稳定地部署在高度利用的 YARN 群集上。


注:本文翻译自:http://mkuthan.github.io/blog/2016/09/30/spark-streaming-on-yarn/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值