storm源码分析研究(八)

2021SC@SDUSC

bolt源码分析(三)

2021SC@SDUSC

本文主要介绍一下bolt接口方面

Storm中定义的Bolt接口主要有IBolt 、IRichBolt、IBasicBolt和IBatchBolt
几者关系如下:
在这里插入图片描述

IBolt.java

IBolt定义了Bolt的功能集合,其代码如下:

public interface IBolt extends Serializable {
  
    void prepare(Map<String, Object> topoConf, TopologyContext context, OutputCollector collector);

    void execute(Tuple input);
    
    void cleanup();
}

Bolt是Storm中的基础运行单位,当其启动并有消息输入时,将调用execute方法来进行处理。 与ISpout类似,IBolt对象在提交时也会被序列化为字节数组,具体的执行节点通过反序列化的方法得到该对象,并调用prepare回调方法c 用户应将复杂对象的初始化放在prepare回调方法中实现,以保证每个具体对象都可以正确初始化。
对象被销毁时,将调用cleanup回调方法,但是Storm并不保证该方法一定被执行。
通常,在execute方法的实现中会对输人消息进行处理,这有可能产生新消息需要发送到下游节点,最后还要对输入的消息进行Ack操作。如果消息处理失败,则需对输入的消息进行Fail操作,这是保证Ack消息系统可以正常工作的基础。

IRichBolt.java

package org.apache.storm.topology;

import org.apache.storm.task.IBolt;
public interface IRichBolt extends IBolt, IComponent {

}

IRichBolt需要同时实现IComponent以及IBolt接口,其含义是一个具有Bolt功能的组件。在实际使用中,IRichBolt是实现Topology组件的主要接口。

IBasicBolt.java

public interface IBasicBolt extends IComponent {
    void prepare(Map<String, Object> topoConf, TopologyContext context);

    void execute(Tuple input, BasicOutputCollector collector);

    void cleanup();
}

IBasicBolt接口的定义与IBolt基本一致,具体的实现要求也与IBolt相同,它与IBolt的区别在于以下两点:
1、它的输出收集器使用的是BasicOutputCollector,并且该参数被放在了execute方法中而不是prepare中。
2、它实现了IComponent接口,这表明它可以用来定义Topology组件。

此接口存在的原因:
IBasicBolt的主要作用是为用户提供一种更简单的Bolt
编写方式。基于IBasicBolt编写的好处是Storm框架本身帮你处理了所发出消息的Ack 、 Fail和Anchor操作,这是由执行器BasicBoltExecutor实现的。

BasicBoltExecutor实现了IRichBolt接口,同时还包含了一个IBasciBolt成员变量用于调用的转发。它是基于装饰模式实现的,其定义如下:

public class BasicBoltExecutor implements IRichBolt {
    public static final Logger LOG = LoggerFactory.getLogger(BasicBoltExecutor.class);

    private IBasicBolt bolt;
    private transient BasicOutputCollector collector;

    public BasicBoltExecutor(IBasicBolt bolt) {
        this.bolt = bolt;
    }

    public void declareOutputFields(OutputFieldsDeclarer declarer) {
        bolt.declareOutputFields(declarer);
    }


    @Override
    public void prepare(Map<String, Object> topoConf, TopologyContext context, OutputCollector collector) {
        bolt.prepare(topoConf, context);
        this.collector = new BasicOutputCollector(collector);
    }

    public void execute(Tuple input) {
        collector.setContext(input);
        try {
            bolt.execute(input, collector);
            collector.getOutputter().ack(input);
        } catch (FailedException e) {
            if (e instanceof ReportedFailedException) {
                collector.reportError(e);
            }
            collector.getOutputter().fail(input);
        }
    }

    public void cleanup() {
        bolt.cleanup();
    }

    public Map<String, Object> getComponentConfiguration() {
        return bolt.getComponentConfiguration();
    }
}

BasicBoltExecutor需要实现IRichBolt接口的原因:

用户实现了IBasicBolt接口的Bolt对象以后,在构建Topology时,Storm会调用TopologyBuilder的setBolt方法设置该Bolt对象。SetBolt方法会用BasicBoltExecutor封装用户的实现类,这是Storm自动帮用户实现的,而且它还会调用可接收IRichBolt参数的重载方法完成Bolt设置。

IBatchBolt.java

public interface IBatchBolt<T> extends Serializable, IComponent {
    void prepare(Map<String, Object> conf, TopologyContext context, BatchOutputCollector collector, T id);

    void execute(Tuple tuple);

    void finishBatch();
}

区别于IBasicBolt接口,IBatchBolt主要用于Storm中的批处理。目前,Storm主要用该接口来实现可靠的消息传输,在这种情况下,批处理会比单一消息处理更为高效。Storm的事务Topology以及Trident主要是基于IBatchBolt的。

相比前面的IBolt、IBasicBolt和IRichBolt, IBatchBolt中多了一个finishBatch方法,它在一个批处理结束时被调用。

prepare方法:
用来初始化一个Batch。在prepare方法中,最后一个参数是通用类型T,它可以用作该Batch的唯一标识。在IBatchBolt衍生的BaseTransactionalBolt中, T将被实例化为TransactionalAttempt。
在目前的Storm实现中,每个事务都会对应一个Batch,而每个Batch的数据都会由一个新仓健的IBatchBolt对象进行处理。于是在prepare方法中,需要传人一个用于标识batch的变量T。而在事务Topology中,Storm则利用TransactionAttempt作为标识。当一个Batch被成功处理之后,该Batch对应的IBatchBolt对象将被销毁,因此用户不能通过IBatchBolt对象自身保存需要在多个Batch间进行共享的数据。
execute方法:
用于处理属于该Batch的消息。
finishBatch方法:
该方法仅当这批消息被处理完时才会被调用。如果BatchBolt同时实现
了ICoranitter的接口,finishBatch方法只有当该Batch之前的所有Batch均被成功处理后才被调用。这既保证了强序关系,同时也是Storm中事务Topology的实现基础。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值