IBolt IRichBolt IBasicBolt IBatchBolt 区分

:IBolt : 定义了Bolt的功能集合,主要有
void prepare(Map stormConf,TopologyContext context, OutputCollector collector);
void execut(e Tuple input);
void cleanup();
三个方法


二: IRichBolt 需要实现IBolt和IComponent接口
public interface IRichBolt extends IBolt, IComponent {
}

三: IBasicBolt: 接口定义与IBolt基本一致,具体的实现要求也与IBolt相同,
区别在于以下两点:
1:他的收集器用的是 BasicOutputCollector,并且该参数放在execute的方法中二不是perpare中
2:他实现了 IComponent 接口
源码:
public interface IBasicBolt extends IComponent {
void prepare(Map stormConf, TopologyContext context);
/**
* Process the input tuple and optionally emit new tuples based on the input tuple.
*
* All acking is managed for you. Throw a FailedException if you want to fail the tuple.
*/
void execute(Tuple input, BasicOutputCollector collector);
void cleanup();
}
为什么会有这个接口,作用是提供一种更简单的Bolt编写方式,基于 IBasicBolt编写的好处是storm框架帮你处理发出消息的Ack,Fail和Anchor操作,这是由执行器 BasicBoltExecutor
实现的。
BasicBoltExecutor 已经帮你实现了IRichBolt
源码:
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) {
_bolt = bolt;
}

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

public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
_bolt .prepare(stormConf, context);
_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();
}
}


四 :IBatchBolt

IBatchBolt主要用于storm中的批处理,目前storm主要用该接口来实现消息的可靠传输,storm的事务Topology以及Trident主要是基于IBatchBolt的,相比以上三个,它多了一个 finishBatch 方法,它在一个批处理结束时候被调用。此外, IBatchBolt还除去了cleanup方法。


public class BatchBoltExecutor implements IRichBolt, FinishedCallback, TimeoutCallback {
public static final Logger LOG = LoggerFactory. getLogger (BatchBoltExecutor. class );

byte [] _boltSer ;
Map<Object, IBatchBolt> _openTransactions ;
Map _conf ;
TopologyContext _context ;
BatchOutputCollectorImpl _collector ;
public BatchBoltExecutor(IBatchBolt bolt) {
_boltSer = Utils. javaSerialize (bolt);
}
@Override
public void prepare(Map conf, TopologyContext context, OutputCollector collector) {
_conf = conf;
_context = context;
_collector = new BatchOutputCollectorImpl(collector);
_openTransactions = new HashMap<>();
}

@Override
public void execute(Tuple input) {
Object id = input.getValue( 0 );
IBatchBolt bolt = getBatchBolt(id);
try {
bolt.execute(input);
_collector .ack(input);
} catch (FailedException e) {
LOG .error( "Failed to process tuple in batch" , e);
_collector .fail(input);
}
}

@Override
public void cleanup() {
}

@Override
public void finishedId(Object id) {
IBatchBolt bolt = getBatchBolt(id);
_openTransactions .remove(id);
bolt.finishBatch();
}

@Override
public void timeoutId(Object attempt) {
_openTransactions .remove(attempt);
}

@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
newTransactionalBolt().declareOutputFields(declarer);
}
@Override
public Map<String, Object> getComponentConfiguration() {
return newTransactionalBolt().getComponentConfiguration();
}
private IBatchBolt getBatchBolt(Object id) {
IBatchBolt bolt = _openTransactions .get(id);
if (bolt== null ) {
bolt = newTransactionalBolt();
bolt.prepare( _conf , _context , _collector , id);
_openTransactions .put(id, bolt);
}
return bolt;
}
private IBatchBolt newTransactionalBolt() {
return Utils. javaDeserialize ( _boltSer , IBatchBolt. class );
}
}

猜你喜欢

转载自blog.csdn.net/cxkaa502401673/article/details/79557361