开发火花流应用程序

时间:2014-09-04 10:23:52

标签: apache-spark spark-streaming

所以我试图解决的问题如下:

  • 我需要一个以特定频率发送消息的数据源
  • 有N个神经网需要单独处理每个消息
  • 所有神经网络的输出都是聚合的,只有当收集到每条消息的所有N个输出时,才应声明消息被完全处理
  • 最后,我应该测量消息完全处理所花费的时间(从发出消息到收集消息的所有N个神经网络输出之间的时间)

我很好奇如何使用火花流来处理这样的任务。

我目前的实现使用3种类型的组件:一个自定义接收器和两个实现Function的类,一个用于神经网络,一个用于最终聚合器。

总的来说,我的应用程序构建如下:

JavaReceiverInputDStream<...> rndLists = jssc.receiverStream(new JavaRandomReceiver(...));

Function<JavaRDD<...>, Void> aggregator = new JavaSyncBarrier(numberOfNets);

for(int i = 0; i < numberOfNets; i++){
    rndLists.map(new NeuralNetMapper(neuralNetConfig)).foreachRDD(aggregator);
}

我遇到的主要问题是,它在本地模式下的运行速度比提交给4节点集群时要快。

我的实现是错误的开头还是其他事情发生在这里?

此处还有一篇完整的帖子http://apache-spark-user-list.1001560.n3.nabble.com/Developing-a-spark-streaming-application-td12893.html,其中详细介绍了前面提到的三个组成部分的实施情况。

1 个答案:

答案 0 :(得分:5)

似乎可能存在大量重复的实例化和对象的序列化。后者可能会在群集中达到你的表现。

您应该尝试仅将您的神经网络实例化一次。您必须确保它们是可序列化的。您应该使用flatMap而不是多个map s + union。这些方面的东西:

// Initialize neural net first
List<NeuralNetMapper> neuralNetMappers = new ArrayList<>(numberOfNets);
for(int i = 0; i < numberOfNets; i++){
    neuralNetMappers.add(new NeuralNetMapper(neuralNetConfig));
}

// Then create a DStream applying all of them
JavaDStream<Result> neuralNetResults = rndLists.flatMap(new FlatMapFunction<Item, Result>() {
    @Override
    public Iterable<Result> call(Item item) {
        List<Result> results = new ArrayList<>(numberOfNets);
        for (int i = 0; i < numberOfNets; i++) {
            results.add(neuralNetMappers.get(i).doYourNeuralNetStuff(item));
        }
        return results;
    }
});

// The aggregation stuff
neuralNetResults.foreachRDD(aggregator);

如果您能够以这种方式初始化网络,则可以节省大量时间。此外,您链接的帖子中包含的union内容似乎没有必要,并且会影响您的效果:flatMap会这样做。

最后,为了进一步调整群集中的效果you can use the Kryo serializer