Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 使用Kafka在长时间运行的Spark作业之间进行通信_Scala_Apache Spark_Apache Kafka_Spark Streaming_Long Running Processes - Fatal编程技术网

Scala 使用Kafka在长时间运行的Spark作业之间进行通信

Scala 使用Kafka在长时间运行的Spark作业之间进行通信,scala,apache-spark,apache-kafka,spark-streaming,long-running-processes,Scala,Apache Spark,Apache Kafka,Spark Streaming,Long Running Processes,我是ApacheSpark新手,需要在我的Spark集群上同时运行几个长期运行的进程(作业)。通常,这些单独的流程(每个流程都是自己的工作)需要相互通信。我暂时考虑使用卡夫卡作为这些过程之间的中间人。因此,高级别的工作对工作沟通如下所示: 作业#1做一些工作,并将消息发布到卡夫卡主题 作业#2被设置为同一卡夫卡主题的流式接收器(使用StreamingContext),消息发布到该主题后,作业#2就会使用它 作业#2现在可以根据它所使用的消息执行一些工作 据我所知,流式上下文正在阻止Spark驱动

我是ApacheSpark新手,需要在我的Spark集群上同时运行几个长期运行的进程(作业)。通常,这些单独的流程(每个流程都是自己的工作)需要相互通信。我暂时考虑使用卡夫卡作为这些过程之间的中间人。因此,高级别的工作对工作沟通如下所示:

  • 作业#1做一些工作,并将消息发布到卡夫卡主题
  • 作业#2被设置为同一卡夫卡主题的流式接收器(使用
    StreamingContext
    ),消息发布到该主题后,作业#2就会使用它
  • 作业#2现在可以根据它所使用的消息执行一些工作
  • 据我所知,流式上下文正在阻止Spark驱动程序节点上运行的侦听器。这意味着,一旦我启动流媒体消费者,如下所示:

    def createKafkaStream(ssc: StreamingContext,
            kafkaTopics: String, brokers: String): DStream[(String, 
            String)] = {
        // some configs here
        KafkaUtils.createDirectStream[String, String, StringDecoder,
            StringDecoder](ssc, props, topicsSet)
    }
    
    def consumerHandler(): StreamingContext = {
        val ssc = new StreamingContext(sc, Seconds(10))
    
        createKafkaStream(ssc, "someTopic", "my-kafka-ip:9092").foreachRDD(rdd => {
            rdd.collect().foreach { msg =>
                // Now do some work as soon as we receive a messsage from the topic
            }
        })
    
        ssc
    }
    
    StreamingContext.getActive.foreach {
        _.stop(stopSparkContext = false)
    }
    
    val ssc = StreamingContext.getActiveOrCreate(consumerHandler)
    ssc.start()
    ssc.awaitTermination()
    
    …现在有两种含义:

  • 司机现在正在拦截和监听卡夫卡的工作;及
  • 当接收到工作(消息)时,它们被发送到任何可用的工作节点,以便实际执行
  • 所以,首先,如果我上面说的任何东西是不正确的或是误导性的,请先纠正我!假设我或多或少是正确的,那么我只是想知道,根据我的标准,是否有一种更具可扩展性或性能的方法来实现这一点。同样,我有两个长时间运行的作业(作业1和作业2)正在Spark节点上运行,其中一个需要能够将工作“发送”给另一个。有什么想法吗

    据我所知,流媒体上下文正在阻止侦听器 在Spark驱动程序节点上运行

    StreamingContext
    (单数)不是阻塞侦听器。它的任务是为流媒体作业创建执行图

    当您开始从卡夫卡读取时,您指定希望每10秒获取一次新记录。从现在起会发生什么取决于您对卡夫卡使用的卡夫卡抽象,或者是通过
    KafkaUtils.createStream
    的接收方方法,或者是通过
    KafkaUtils.createDirectStream
    的无接收方方法

    通常,在这两种方法中,数据都是从卡夫卡中消耗出来的,然后发送给每个Spark worker进行并行处理

    然后我只是想知道是否有更具可扩展性或性能的 如何做到这一点


    这种方法具有高度可扩展性。使用无接收器方法时,每个Kafka分区映射到给定RDD中的Spark分区。您可以通过增加Kafka中的分区数量或通过重新分区Spark中的数据(使用
    DStream.repartition
    )来提高并行性。我建议测试此设置,以确定它是否符合您的性能要求。

    谢谢@Yuval(+1),如果您不介意的话,请回答以下几个问题!(1) 您能否首先确认,为了针对Spark上的卡夫卡主题设置“竞争消费者”,我需要每簇1个消费者?对于接收器和无接收器配置,这是真的吗?(2) 什么时候使用接收器与无接收器方法的一般指导原则是什么?(3)当您说“当您开始从卡夫卡读取时,您指定您希望每10秒获取一次新记录…”时,这是在哪里配置的?它可以设置为10秒以外的值吗?最后,(4)使用接收方方法时,Kafka分区映射到什么?再次非常感谢@smeeb 1)你所说的“竞争消费者”是什么意思?2) 我通常建议使用直接流式方法,它是在Spark 1.3.0中引入的,具有许多优点。我建议好好读一读。3) 在这里配置:
    val ssc=new StreamingContext(sc,秒(10))
    。4) 在基于接收器的方法中,没有分区映射。如果您想同时从Kafka读入,您必须连接多个使用者,这意味着您必须执行多个
    KafkaUtils.createStream
    调用并合并它们。再次感谢@Yuval(+1)!所谓“竞争消费者”,我指的是多个消费者线程都在收听和消费来自同一卡夫卡主题的消息。因此,我上面的第一个问题是想澄清我对Spark上的流媒体消费者的理解,即:每个并发消费者必须在自己的Spark集群上运行(对还是错?)。或者我可以从
    consumerHandler
    内部多次调用
    KafkaUtils.createDStream
    ,每次调用都会为我设置一个不同的“竞争”消费者线程(在同一集群上)。如果使用直接流方法,则两者都不需要。Spark将在工人之间划分卡夫卡偏移量,工人可以同时读取卡夫卡。直接流方法中的基数是kafka分区和spark RDD分区之间的1:1。阅读主题的并发性基于spark Worker的数量,spark Worker可以使用
    rdd从Kafka.BTW读取偏移量。foreachRDD中的collect
    将导致它们将整个数据集发送回驱动程序。你肯定不想这样。谢谢@Yuval(+1),有什么更好/更有效的方法可以访问正在使用的单个邮件?这不是我的初衷,我只是刚刚接触API,所以请随时更新我的代码!您可以使用
    rdd.foreach