前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【实战篇】如何优雅的停止你的 Spark Streaming Application

【实战篇】如何优雅的停止你的 Spark Streaming Application

作者头像
codingforfun
发布2018-08-24 15:06:34
1.4K0
发布2018-08-24 15:06:34
举报
文章被收录于专栏:牛肉圆粉不加葱

Spark 1.3及其前的版本

你的一个 spark streaming application 已经好好运行了一段时间了,这个时候你因为某种原因要停止它。你应该怎么做?直接暴力 kill 该 application 吗?这可能会导致数据丢失,因为 receivers 可能已经接受到了数据,但该数据还未被处理,当你强行停止该 application,driver 就没办法处理这些本该处理的数据。

所以,我们应该使用一种避免数据丢失的方式,官方建议调用 StreamingContext#stop(stopSparkContext: Boolean, stopGracefully: Boolean),将 stopGracefully 设置为 true,这样可以保证在 driver 结束前处理完所有已经接受的数据。

一个 streaming application 往往是长时间运行的,所以存在两个问题:

  1. 应该在什么时候去调用 StreamingContext#stop
  2. 当 streaming application 已经在运行了该怎么去调用 StreamingContext#stop

how

通过 Runtime.getRuntime().addShutdownHook 注册关闭钩子, JVM将在关闭之前执行关闭钩子中的 run 函数(不管是正常退出还是异常退出都会调用),所以我们可以在 driver 代码中加入以下代码:

代码语言:javascript
复制
Runtime.getRuntime().addShutdownHook(new Thread() {
  override def run() {
    log("Shutting down streaming app...")
    streamingContext.stop(true, true)
    log("Shutdown of streaming app complete.")
  }
})

这样就能保证即使 application 被强行 kill 掉,在 driver 结束前,streamingContext.stop(true, true)也会被调用,从而保证已接收的数据都会被处理。

Spark 1.4及其后的版本

上一小节介绍的方法仅适用于 1.3及以前的版本,在 1.4及其后的版本中不仅不能保证生效,甚至会引起死锁等线程问题。在 1.4及其后的版本中,我们只需设置 spark.streaming.stopGracefullyOnShutdowntrue 即可达到上一小节相同的效果。

下面来分析为什么上一小节介绍的方法在 1.4其后的版本中不能用。首先,需要明确的是:

  1. 当我们注册了多个关闭钩子时,JVM开始启用其关闭序列时,它会以某种未指定的顺序启动所有已注册的关闭钩子,并让它们同时运行
  2. 万一不止一个关闭钩子,它们将并行地运行,并容易引发线程问题,例如死锁

综合以上两点,我们可以明确,如果除了我们注册的关闭钩子外,driver 还有注册了其他钩子,将会引发上述两个问题。

在 StreamingContext#start 中,会调用

代码语言:javascript
复制
ShutdownHookManager.addShutdownHook(StreamingContext.SHUTDOWN_HOOK_PRIORITY)(stopOnShutdown)

该函数最终注册一个关闭钩子,并会在 run 方法中调用 stopOnShutdown

代码语言:javascript
复制
  private def stopOnShutdown(): Unit = {
    val stopGracefully = conf.getBoolean("spark.streaming.stopGracefullyOnShutdown", false)
    logInfo(s"Invoking stop(stopGracefully=$stopGracefully) from shutdown hook")
    // Do not stop SparkContext, let its own shutdown hook stop it
    stop(stopSparkContext = false, stopGracefully = stopGracefully)
  }

stopOnShutdown 中会根据 stopGracefully 的值来决定是否以优雅的方式结束 driver,而 stopGracefully 的值由 spark.streaming.stopGracefullyOnShutdown 决定。结合上文,也就能说明为什么 spark.streaming.stopGracefullyOnShutdown能决定是否优雅的结束 application 和为什么上一小节的方法不适用与 1.4及其后版本。


本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016.04.11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spark 1.3及其前的版本
  • how
  • Spark 1.4及其后的版本
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档