• 如何优雅地停止Spark Streaming Job


      由于streaming流程序一旦运行起来,基本上是无休止的状态,除非是特殊情况,否则是不会停的。因为每时每刻都有可能在处理数据,如果要停止也需要确认当前正在处理的数据执行完毕,并且不能再接受新的数据,这样才能保证数据不丢不重。

      同时,也由于流程序比较特殊,所以也不能直接kill -9这种暴力方式停掉,直接kill的话,就有可能丢失数据或者重复消费数据。

      

      下面介绍如何优雅的停止streaming job。

      第一种:人工手动停止

    •   程序里设置如下参数:
    sparkConf.set("spark.streaming.stopGracefullyOnShutdown","true")//优雅的关闭
    
    •   然后按照下面步骤操作
      • 通过Hadoop 8088页面找到运行的程序
      • 打开spark UI的监控页面
      • 打开executor的监控页面
      • 登录Linux找到驱动节点所在的机器IP以及运行的端口号
      • 然后执行一个封装好的命令
        sudo ss -tanlp |  grep 5555 |awk '{print $6}'|awk  -F, '{print $2}' | sudo  xargs kill -15

        这种方式显然是比较复杂的。

      第二种:使用HDFS系统做消息通知

        在驱动程序中,加上一段代码,作用就是每隔一段时间扫描HDFS上一个文件,如果发现这个文件存在,就调用StreamContext的Stop方法,优雅的停止程序。

        这里的HDFS可以换成reids、zk、hbase、db,唯一的问题就是依赖了外部的一个存储系统来达到消息通知的目的。

        使用这种方式,停止程序就比较简单。登录有HDFS客户端的机器,然后touch一个空文件到指定目录,等到间隔的扫描时间,发现有文件存在,就需要关闭程序了。

        废话不多说,上代码

        ssc.start()
    
        //check interval
        val checkIntervalMillis = 15000
        var isStopped = false
    
        println("before while")
        while (!isStopped) {
          println("calling awaitTerminationOrTimeout")
          isStopped = ssc.awaitTerminationOrTimeout(checkIntervalMillis)
          if (isStopped)
            println("confirmed! The streaming context is stopped. Exiting application...")
          else
            println("Streaming App is still running.")
    
          println("check file exists")
          if (!stopFlag) {
            val fs = FileSystem.get(new URI("hdfs://192.168.156.111:9000"),new Configuration())
            stopFlag = fs.exists(new Path("/stopMarker/marker"))
          }
          if (!isStopped && stopFlag) {
            println("stopping ssc right now")
            ssc.stop(true, true)
          }
        }
    

      第三种:内部暴露一个socket或者http端口用来接收请求,等待除法关闭流程序

        这种方式需要在driver启动一个socket线程,或者http服务。比较推荐使用http服务,因为socket有点偏底层,处理起来稍微复杂。

        如果使用http服务,可以直接用内嵌的jetty,对外暴露一个http接口。Spark UI页面用的也是内嵌的jetty提供服务,所以不需要在pom文件引入额外的依赖,在关闭的时候,找到驱动所在的IP,就可以直接通过crul或者浏览器直接关闭流程序

        找到驱动程序所在的IP,可以在程序启动的log中看到,也可以在spark master UI界面上找到,这种方式不依赖任何的存储系统,仅仅在部署的时候需要一个额外的端口号暴露http服务。

    推荐使用第二种或第三种,如果想最大程度的减少对外部系统的依赖,推荐使用第三种。

    参考文档:https://www.linkedin.com/pulse/how-shutdown-spark-streaming-job-gracefully-lan-jiang

  • 相关阅读:
    高手写出的是天使,而新手写的,可能是魔鬼!(Javascript这样的脚本语言,由于太灵活)
    netsuite nlapiLineInit
    JavaScript数组操作
    jQuery Prototype 对比
    iframe 兼容 ie firefox 提交
    JavaScript的9个陷阱及评点 转载
    网站文档如何在最短的时间内被Google收录?
    server端的beforeload事件 在nlapiLoadRecord 中将会被出发
    email feedback
    netsuite you can't submit this form due to unexpected error
  • 原文地址:https://www.cnblogs.com/zbw1112/p/11959965.html
Copyright © 2020-2023  润新知