当我使用风暴时,如何确保具有多个输入的螺栓仅在所有输入到达时处理?

时间:2016-08-02 07:23:17

标签: apache-storm

拓扑看起来像这样。 The Topology :

如何确保具有多个输入的螺栓仅在所有输入到达时处理?

2 个答案:

答案 0 :(得分:0)

每个传入的元组都会调用

Bolt.execute(),无论生成器是什么(并且您无法更改它)。如果要同时处理来自不同生产者的多个元组,则需要编写自定义UDF代码。

  1. 您需要为每个生产者提供一个输入缓冲区,它可以缓冲传入的元组(可能是LinkedList<Tuple>作为螺栓成员)
  2. 对于每个传入的元组,您将元组添加到相应的缓冲区(您可以通过。input.getSourceComponent()
  3. 访问元组元数据中的生产者信息。
  4. 将元组添加到缓冲区后,检查每个缓冲区是否包含至少一个元组:如果是,则从每个缓冲区中取一个元组进行处理(处理后,再次检查缓冲区,直到缓冲区为空) - 不,只是返回,不处理任何事情。

答案 1 :(得分:0)

您可能需要查看here(请参阅批处理)。对于处理更复杂操作(例如多个输入元组上的聚合)的螺栓,您需要扩展BaseRichBolt并自行控制锚定机制。

为此,您需要声明自己的输出收集器,如下所示:

private OutputCollector outputCollector;

然后通过覆盖prepare方法初始化它:

@Override
public void prepare(Map map, TopologyContext topologyContext, OutputCollector outputCollector) {
    this.outputCollector = outputCollector;
}

您对BaseRichBolt的执行方法只接收一个元组作为参数,您需要能够执行逻辑来维护锚点并在发出时使用它们。

private final List<Tuple> anchors = new ArrayList<Tuple>();

@Override
public void execute(Tuple tuple) {
    if (!isTupleAggregationComplete(anchors, tuple)) {
        anchors.add(tuple);
        return;
    }

    // do your computations here!

    collector.emit(anchors, new Values(foo,bar,xpto));

    anchors.clear();
}

您应该使用必要的逻辑来实现isTupleAggregationComplete,该逻辑检查螺栓是否具有继续处理所需的所有必要信息。