火花流和批处理模式之间的代码重用不同的元素

时间:2014-12-03 15:04:32

标签: java apache-spark spark-streaming

我是Spark新手,我想使用spark streaming和spark batch来实现lambda架构。

在网上看到我发现了以下文章:

http://blog.cloudera.com/blog/2014/08/building-lambda-architecture-with-spark-streaming/

这对我的一些分析很好,但我不认为这个解决方案在必须找到不同元素的情况下是可行的。

如果要在JavaRDD上查找不同的元素,可以使用distinct方法。 DStreams是一组RDD,所以如果你应用

transform((rdd) -> rdd.distinct()) 
在Dstream上的

方法,你将在流的每个rdd上执行distinct,这样你就可以在每个RDD中找到不同的元素,而不是整个DStream。

可能写得有点令人困惑,所以让我用一个例子来澄清:

我有以下要素:

Apple
Pear
Banana
Peach
Apple
Pear

在批处理应用中:

JavaRDD<String> elemsRDD=sc.textFile(exFilePath).distinct() 

子RDD将包含:

Apple
Pear
Banana
Peach

如果我理解正确,这应该是流的行为:

假设我们的批处理时间为1秒,窗口为2秒:

第一个RDD:

Apple  
Pear
Banana

第二个RDD:

Peach
Apple
Pear

JavaDStream<String> elemsStream=(getting from whathever source)
childStream = elemsStream.transform((rdd) -> rdd.distinct())
childStream.forEachRDD...

将以2个Rdds结束: 第一:

Apple  
Pear
Banana

第二

Peach
Apple
Pear

这是对RDD的明显尊重,但不尊重DStream。

我对Streaming部分的解决方案如下:

JavaDStream<HashSet<String>> distinctElems = elemsStream.map(
                (elem) -> {
                    HashSet<String> htSet = new HashSet<String>();
                    htSet.add(elem);
                    return htSet;
                }).reduce((sp1, sp2) -> {
                    sp1.addAll(sp2);
                    return sp1;
                });

通过这种方式,结果是:

Apple
Pear
Banana
Peach

作为批处理模式。 但是,此解决方案将需要维护开销,并且存在因重复代码库而导致错误的风险。

有没有更好的方法来达到同样的结果,尽可能多地重用批处理模式的代码?

提前致谢。

1 个答案:

答案 0 :(得分:1)

您的解决方案很优雅。

我有其他解决方案,它不如你的优雅,但我不知道它是否更有效。这是我基于mapToPairFunction

的解决方案
JavaPairDStream<String, Integer> distinctElems = elemsStream
       .mapToPair(event -> new Tuple2<String, Integer>(event,1));
distinctElems = distinctElems.reduceByKey((t1, t2) -> t1);

我认为这样更有效但我无法测试它。