Ephemeral Spark Streaming..Shutdown以编程方式

时间:2018-03-07 00:10:34

标签: apache-spark spark-streaming

背景

我是Spark流媒体的新手,也是scala和spark的新手。

  • 我有一个java大数据包装器应用程序,它接受数据输入并生成libsvm和/或csv格式数据。这个应用程序独立于spark。

  • 我正在开发的功能允许java应用程序打开套接字,连接到spark主节点上的springboot应用程序,指示应用程序打开spark流,然后将其数据流式传输到spark。

  • 数据流后,java app关闭。

  • 大部分工作正常,但我无法关闭火花流上下文,所以一旦java端关闭,我就不停了

  

ERROR ReceiverTracker:流0的注销接收器:重新启动   接收器延迟2000ms:连接被拒绝

DStream读取文件信号的结尾。我已经确认收到并解析了

问题

然而,尽管已阅读文档,但我无法找到以编程方式关闭StreamingContext的方法。实际上,我在线阅读StreamingContext.stop(true, true)会导致问题。

我的代码如下。任何帮助都将深表感谢。

(注意:logger.info("Stopping")永远不会记录到文件中)

var:stop=false;

@throws(classOf[IKodaMLException])
def  startStream(ip:String,port:Int):Unit=
{
 try {
  val ssc = getSparkStreamingContext(fieldVariables)
  ssc.checkpoint("./ikoda/cp")

  val lines = ssc.socketTextStream(ip, port, StorageLevel.MEMORY_AND_DISK_SER)
  lines.print

  val lmap=lines.map
  {
    l =>
      if(l.contains("IKODA_END_STREAM"))
        {
          stop=true;

        }

      .....do stuff and return processed line
  }

 if(stop)
    {
      logger.info("Stopping")
      ssc.stop(true,true)
    }


    lmap.foreachRDD {
      r =>
        if(r.count() >0) {
          .......do more stufff
        }
        else
          {
            logger.info("Empty RDD. No data received")
          }
    }
  ssc.start()
  ssc.awaitTermination()
}

1 个答案:

答案 0 :(得分:0)

更新:这个答案似乎是事实上正确的,但在概念上是错误的。我认为提供了更好的答案in this post

这个答案有点初步。它回答了问题,但没有解决问题。其他投入是最受欢迎的。

  • 首先,文档说明以编程方式关闭是可以的。但是,我注意到在关闭之前抛出了一个或两个连接相关的异常。但是,即使告诉SparkContext与流一起关闭,它似乎也不会这样做。所以以编程方式关闭似乎是不明智的。除非我可以重新启动流,否则该项目没有实际意义。

  • 其次,在流式传输过程中应用于StreamingContext的唯一代码是直接引用DSTream的代码,所以很明显上面代码中的stop()调用(上面讨论过)是错误的。

  • 第三,在驱动程序上确实发生了流式传输(据我所知)。因此可以创建字段变量,并在DStream循环,映射等内部引用。

  • 可以创建一个监视关闭调用的Thread作为字段级布尔值。然后调用Streaming Context并关闭。

线程

var stopScc=false

private def stopSccThread(): Unit = {
val thread = new Thread {
  override def run {

    var continueRun=true
    while (continueRun) {
      logger.debug("Checking status")
      if (stopScc == true) {
        getSparkStreamingContext(fieldVariables).stop(true, true)
        logger.info("Called Stop on Streaming Context")
        continueRun=false


      }
      Thread.sleep(50)
    }
  }
}
thread.start

}

@throws(classOf[IKodaMLException])
def startStream(ip: String, port: Int): Unit = {

try {
  val ssc = getSparkStreamingContext(fieldVariables)
  ssc.checkpoint("./ikoda/cp")

  val lines = ssc.socketTextStream(ip, port, StorageLevel.MEMORY_AND_DISK_SER)
  lines.print


  val lmap = lines.map {
    l =>

      if (l.contains("IKODA_END_STREAM")) {
        stopScc = true
      }
      l
  }


  lmap.foreachRDD {
    r =>
      if (r.count() > 0) {
        logger.info(s"RECEIVED: ${r.toString()} first: ${r.first().toString}")
        r.saveAsTextFile("./ikoda/test/test")
      }
      else {
        logger.info("Empty RDD. No data received")
      }
  }
  ssc.start()

  ssc.awaitTermination()
}
catch {
  case e: Exception =>
    logger.error(e.getMessage, e)
    throw new IKodaMLException(e.getMessage, e)
}