• JStorm与Storm源码分析(六)--收集器 IOutputCollector 、OutputCollector


    在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源码分析笔记整理。 
    欢迎关注下面二维码进行技术交流: 

  • 相关阅读:
    mysql5.7版本centos8环境修改my.cnf配置文件
    mysql5.7使用r2dbc持久层框架性能飙升,一小时插入623万数据,平均每秒插入1723条
    mysql5.7决定SQL中IN条件是否走索引的成本计算,mysql中的index dive是在两个区间之间计算有多少条记录的方式
    mysql5.7的SQL执行成本计算,IO成本和CPU成本,单表查询成本,多表连接查询成本,执行成本决定mysql是否走索引,.OPTIMIZER_TRACE,cost_info
    mysql5.7基于块的嵌套循环连接(Block Nested-Loop Join)
    时间复杂度计算法
    mysql5.7索引合并:交集、并集,EXPLAIN例子
    mysql5.7分区表
    mysql5.7的随机IO和顺序IO
    MySQL5.7二级索引+回表的MRR优化技术
  • 原文地址:https://www.cnblogs.com/RoseVorchid/p/7266576.html
Copyright © 2020-2023  润新知