如何优雅地关闭SparkStreaming

参考2(已经过时)

给出来一个方法,在scala中sys.ShutdownHookThread可以捕获SIGTERM方法,所以当收到kill -SIGTERM时,能够优雅的退出;

def main(args: Array[String]) {

  // Prepare your environment
  
  val ssc = new StreamingContext(conf, Seconds(batchDurationInSec))
  
  // Do your processing
  
  sys.ShutdownHookThread {
      log.info("Gracefully stopping Spark Streaming Application")
      ssc.stop(true, true)
      log.info("Application stopped")
  }
  
  ssc.start
  ssc.awaitTermination
  
}

参考1

上述方案在Saark1.4之后不可使用,会导致死锁问题。现有一下两种方案:

方案1 (推荐但方案需要讨论)

第一种方案是使用spark.streaming.stopGracefullyOnShutdown(默认是false),这个参数就是为了解决Spark优雅关闭问题,开发者不需要调用ssc.stop(),相反他们需要做的是发送SIGTERM信号至Driver。在实际的实践中:

  1. 基于SparkUI查找那个NameNode正运行着Driver进程,在yarn-cluster模式中AM和Driver进程运行在同一个Container中;
  2. 登录该机器,ps -ef |grep java |grep ApplicationMaster|grep applicationId找到PID,注意校验是不是你的进程;
  3. kill -SIGTERM 发送SIGTERM信号;

执行完上述步骤,结果如下:

17/02/02 01:31:35 ERROR yarn.ApplicationMaster: RECEIVED SIGNAL 15: SIGTERM

17/02/02 01:31:35 INFO streaming.StreamingContext: Invoking stop(stopGracefully=true) from shutdown hook

...

17/02/02 01:31:45 INFO streaming.StreamingContext: StreamingContext stopped successfully

17/02/02 01:31:45 INFO spark.SparkContext: Invoking stop() from shutdown hook

...

17/02/02 01:31:45 INFO spark.SparkContext: Successfully stopped SparkContext

...

17/02/02 01:31:45 INFO util.ShutdownHookManager: Shutdown hook called

需要注意的事项

  1. spark.yarn.maxAppAttempts默认是跟Yarn配置中yarn.resourcemanager.am.max-attempts一致的,默认值为2, 如果你不变更该值,你kill掉之后,AM/Driver依然会启动一个,你必须停止第二次;所以当启动时候设置--conf spark.yarn.maxAppAttempts=1
  2. 不推荐yarn application -kill 方法, 这个命令会发送一个SIGTERM信号至container,但接着会发送一个SIGTERM信号,这个时间间隔是由yarn.nodemanager.sleep-delay-before-sigkill.ms(默认250ms)决定,讲该值设置为60000ms,依然不能正常工作,日志只有这两行,如下:
17/02/02 12:12:27 ERROR yarn.ApplicationMaster: RECEIVED SIGNAL 15: SIGTERM

17/02/02 12:12:27 INFO streaming.StreamingContext: Invoking stop(stopGracefully=true) from shutdown hook

方案2 (推荐)

取代SIGTERM信号,可以通过另外一种方式来完成优雅地关闭。一种方式是,在HDFS中设置一个标记文件,定期地校验该标记文件,如果该文件存在,则调用ssc.stop(true, true);或者, 启动一个监听端口,当该端口监听到信号时,则触发优雅关闭;

参考

  1. https://www.linkedin.com/pulse/how-shutdown-spark-streaming-job-gracefully-lan-jiang
  2. https://metabroadcast.com/blog/stop-your-spark-streaming-application-gracefully
  3. https://github.com/lanjiang/streamingstopgraceful

你可能感兴趣的:(如何优雅地关闭SparkStreaming)