在Storm中,多个地方使用了IOutputCollector收集器接口,收集器OutputCollector的接口就是IOutputCollector。所以有必要对接口IOutputCollector进行解读和分析.IOutputCollector的源码如下:
/** * @ClassName: IOutputCollector接口扩展了IErrorReporter, * 并定义了一些基本方法 */ public interface IOutputCollector extends IErrorReporter { /** * 用来向外发送数据,它的返回值是该消息所有发送目标的TaskId集合 * 输入参数: * streamId:消息将被输出到的流; * anchors:输出消息的标记,通常代表该条消息是由哪些消息产生的,主要用于消息的Ack系统; * tuple:要输出的消息,为一个Object列表 */ List<Integer> emit(String streamId, Collection<Tuple> anchors, List<Object> tuple); /** * 与上述方法emit类似,区别在于,emitDirect方法发送的消息只有指定taskId的Task才可以接收. * 该方法要求streamId对应的流必须为直接流而且接收端的Task必须通过直接分组的方式来接收消息,否则会抛出异常. * 这也就意味着:如果没有下游节点接收该消息,则此类消息其实并没有真正被发送 */ void emitDirect(int taskId, String streamId, Collection<Tuple> anchors, List<Object> tuple); /** * ack和fail方法用来记录消息是否被成功处理 */ void ack(Tuple input); void fail(Tuple input); }
IOutputCollector 默认实现类OutputCollector,它实际上是一个代理类,持有IOutputCollector 类型的对象。emit、emitDirect等方法具体的执行都是通过IOutputCollector类型的对象调用相应的方法来实现的.
其定义如下:
/** * OutputCollector实现了接口IOutputCollector, * 其主要作用是用于从IRichBolt向外发送数据; * OutputCollector是一个代理类,它持有一个IOutputCollector类型的实例(该对象在Clojure中定义) */ public class OutputCollector implements IOutputCollector { /** * 持有一个IOutputCollector类型的实例 */ private IOutputCollector _delegate; public OutputCollector(IOutputCollector delegate) { _delegate = delegate; } /** * 定义了emit的各类重载方法 * 说明如下: * 若未传入streamId,则使用default作为流序号; * 若未传入anchor,则使用null作为标记; * 若传入的anchor不是列表对象,则将其转化为列表对象. */ public List<Integer> emit(String streamId, Tuple anchor, List<Object> tuple) { return emit(streamId, Arrays.asList(anchor), tuple); } public List<Integer> emit(String streamId, List<Object> tuple) { return emit(streamId, (List) null, tuple); } public List<Integer> emit(Collection<Tuple> anchors, List<Object> tuple) { return emit(Utils.DEFAULT_STREAM_ID, anchors, tuple); } public List<Integer> emit(Tuple anchor, List<Object> tuple) { return emit(Utils.DEFAULT_STREAM_ID, anchor, tuple); } public List<Integer> emit(List<Object> tuple) { return emit(Utils.DEFAULT_STREAM_ID, tuple); } /** * 定义了emitDirect的各类重载方法 * 说明如下: * 若未传入streamId,则使用default作为流序号; * 若未传入anchor,则使用null作为标记; * 若传入的anchor不是列表对象,则将其转化为列表对象. */ public void emitDirect(int taskId, String streamId, Tuple anchor, List<Object> tuple) { emitDirect(taskId, streamId, Arrays.asList(anchor), tuple); } public void emitDirect(int taskId, String streamId, List<Object> tuple) { emitDirect(taskId, streamId, (List) null, tuple); } public void emitDirect(int taskId, Collection<Tuple> anchors, List<Object> tuple) { emitDirect(taskId, Utils.DEFAULT_STREAM_ID, anchors, tuple); } public void emitDirect(int taskId, Tuple anchor, List<Object> tuple) { emitDirect(taskId, Utils.DEFAULT_STREAM_ID, anchor, tuple); } public void emitDirect(int taskId, List<Object> tuple) { emitDirect(taskId, Utils.DEFAULT_STREAM_ID, tuple); } /** * 实现了IOutputCollector接口,在代理对象中实现了这些方法 */ @Override public List<Integer> emit(String streamId, Collection<Tuple> anchors, List<Object> tuple) { return _delegate.emit(streamId, anchors, tuple); } @Override public void emitDirect(int taskId, String streamId, Collection<Tuple> anchors, List<Object> tuple) { _delegate.emitDirect(taskId, streamId, anchors, tuple); } @Override public void ack(Tuple input) { _delegate.ack(input); } @Override public void fail(Tuple input) { _delegate.fail(input); } @Override public void reportError(Throwable error) { _delegate.reportError(error); } }
注:学习李明等老师Storm源码分析笔记整理。
欢迎关注下面二维码进行技术交流: