package org.apache.storm.trident.operation;
import org.apache.storm.trident.tuple.TridentTuple;
public interface Aggregator<T> extends Operation {
T init(Object batchId, TridentCollector collector);
void aggregate(T val, TridentTuple tuple, TridentCollector collector);
void complete(T val, TridentCollector collector);
}
Aggregator的接口定义如上述代码所示,共包含三个method:init、aggregate和complete。在Aggregator中泛型变量T起到一个很大的作用,他是Aggregate计算过程中中间状态的保存者。
- 在一个batch开始进行aggregate处理之前,框架会调用Aggregator的init方法生成一个初始的T类型的实例,用以保存每一次aggregate调用的中间结果。
- 每来一个touple,框架调用一次Aggregator.aggregate()方法,方法的参数是步骤1中生成的T类型的中间变量以及touple。Aggregator根据上一次的执行结果与本次的touple进行本次运算。
- 一个batch的所有touple运算完成后,框架调用Aggregator的complete函数,进行本batch的收尾工作
下面我们看一下AggregateProcessor的实现。AggregatorProcessor是Aggregate操作背后的基石,他负责完成Aggregattor的生命周期管理和相关接口的调用。
@Override
public void startBatch(ProcessorContext processorContext) {
_collector.setContext(processorContext);
processorContext.state[_context.getStateIndex()] = _agg.init(processorContext.batchId, _collector);
}
如上面代码所示,AggregateProcessor在startBatch函数中,通过调用Aggregattor.init方法完成中间状态实例的生成,即上述文章中T类型的实例。
@Override
public void execute(ProcessorContext processorContext, String streamId, TridentTuple tuple) {
_collector.setContext(processorContext);
_agg.aggregate(processorContext.state[_context.getStateIndex()], _projection.create(tuple), _collector);
}
每来一个touple,AggregateProcessor会执行execute方法,在该方法中会将中间变量以及touple传入给Aggregattor的aggregate方法。
@Override
public void finishBatch(ProcessorContext processorContext) {
_collector.setContext(processorContext);
_agg.complete(processorContext.state[_context.getStateIndex()], _collector);
}
在一个batch处理完成后,finishBatch方法会最终调用complete方法,完成整个‘聚集’操作。