我是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
作为批处理模式。 但是,此解决方案将需要维护开销,并且存在因重复代码库而导致错误的风险。
有没有更好的方法来达到同样的结果,尽可能多地重用批处理模式的代码?
提前致谢。
答案 0 :(得分:1)
您的解决方案很优雅。
我有其他解决方案,它不如你的优雅,但我不知道它是否更有效。这是我基于mapToPairFunction
的解决方案JavaPairDStream<String, Integer> distinctElems = elemsStream
.mapToPair(event -> new Tuple2<String, Integer>(event,1));
distinctElems = distinctElems.reduceByKey((t1, t2) -> t1);
我认为这样更有效但我无法测试它。