我的火花流媒体节目的流程

时间:2017-07-07 19:23:17

标签: scala apache-spark apache-kafka spark-streaming

关于我的火花流程序流程的小问题。

我有这个功能:

def parse(msg: String): Seq[String]

实际上分裂了一个好的"消息分成多个字符串,如果字符串是"坏",则返回一个空的Seq。

我正在阅读来自kafka主题的消息,我想将解析结果发送到两个不同的主题: 如果消息是" good",则将解析结果发送到主题" good_msg_topic" 如果消息是"坏",请发送" bad"消息到主题" bad_msg_topic"

为此,我做到了这一点:

stream.foreachRDD(rdd => {
  val res = rdd.map(msg => msg.value() -> parse(msg.value()))

  res.foreach(pair => {
    if (pair._2.isEmpty) {
      producer.send(junkTopic, pair._1)
    } else {
      pair._2.foreach(m => producer.send(splitTopic, m))
    }
  })
})

但是,我觉得这不是最佳选择。使用Map对象将原始消息与结果相关联可能会减慢进程...

我从Spark和Scala开始,所以我认为可以做得更好。

我对如何改善这一点有什么想法?如果您认为更好,也可以更改解析函数的签名。

谢谢

1 个答案:

答案 0 :(得分:3)

如果您还没有测量过并发现瓶颈,我不会太担心性能。

我能想到的一个可能使代码更清晰的是使用ADT来描述结果类型:

sealed trait Result
case class GoodResult(seq: Seq[String]) extends Result
case class BadResult(original: String) extends Result

parse返回Result

def parse(s: String): Result

然后在map而不是DStream上使用RDD

stream
.map(msg => parse(msg.value())
.foreachRDD { rdd => 
   rdd.foreach { result => 
     result match {
       case GoodResult(seq) => seq.foreach(value => producer.send(splitTopic, value))
       case BadResult(original) => producer.send(junkTopic, original)
     }
   }
}