Spark Streaming - 基于过滤器Param拆分输入流的最佳方法

时间:2017-07-04 09:55:52

标签: apache-spark machine-learning apache-kafka spark-streaming apache-spark-mllib

我目前尝试创建某种监控解决方案 - 一些数据写入kafka,我使用Spark Streaming读取这些数据并进行处理。

为了预处理机器学习和异常检测的数据,我想根据一些过滤器参数拆分流。到目前为止,我已经了解到DStreams本身不能分成几个流。

我主要面临的问题是许多算法(如KMeans)只采用连续数据,而不是像以下那样的离散数据。 url或其他一些String。

理想情况下,我的要求是:

  • 从kafka读取数据并根据我读到的内容生成字符串列表
  • 根据字符串列表生成多个流 - (拆分流,过滤器流或任何最佳做法)
  • 使用这些流为每个Stream训练不同的模型以获得基线,然后比较后来与基线相关的所有内容

我很乐意得到任何建议如何处理我的问题。我无法想象Spark中没有涵盖这种情况 - 但是直到现在我还没有找到可行的解决方案。

1 个答案:

答案 0 :(得分:3)

我认为使用过滤器和地图从原始创建衍生DStream应该足够了:

val numericFeaturesDStream = originalDStream.filter(e => predicate(e)).map(e => extractFeatures(e))
val otherNumericFeaturesDStream = originalDStream.filter(e => predicate2(e)).map(e => extractOtherFeatures(e))

请注意,这些filtermap步骤可以在一个collect步骤中合并(不要与将数据传递给驱动程序的无参数RDD.collect混淆!!!)

val featuresStream = originalDStream.transform(rdd => 
  rdd.collect{case (a,b,c,d,e) if c=="client" => Vectors.parse(a)}
)
streamingKMeans.trainOn(featuresStream)

我们还可以将一组动态过滤的DStream保存到某个集合中。在这里,我们使用包含我们用于过滤的密钥的地图:

originalDStream.cache() // important for performance when a DStream is branched out.
// filterKeys: Set[String] 
val dstreamByFilterKey = filterKeys.map(key => key -> originalDStream.filter(e => (getKey(e)==key)))
// do something with the different DStreams in this structure ...

这些片段是用实际逻辑完成的代码示例。