一. spout
spout中最先调用的是open方法。
spout中nextTuple() 、ack() 以及 fail() 处于同一个线程中,并被周期性地调用。nextTuple()中需要适时释放控制,使其他线程有机会调用执行操作:
/**
* The nextuple it is called forever, so if we have been readed the file
* we will wait and then return
*/
if(completed){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//Do nothing
}
return;
}
b1.p14
public void execute(Tuple input) {
String sentence = input.getString(0);
String[] words = sentence.split(" ");
for(String word : words){
word = word.trim();
if(!word.isEmpty()){
word = word.toLowerCase();
//Emit the word
List a = new ArrayList();
a.add(input);
collector.emit(a,new Values(word)); //这里是emit(Collection<Tuple> anchors, List<Object> tuple)
}
}
// Acknowledge the tuple
collector.ack(input);
}
容错方面
OutputCollector.emit(Tuple,List<Object>)方法可以设置anchor,使之后的处理中如果发生错误或未处理完时,可以从发最初的Spout中的tuple.
可以设置多个anchor : OutputCollector.emit(List<Tuple>, List<Object>)这样当后面的处理发生问题时可以从放每个锚tuple。
OutputCollector有ack和fail方法,直接调用fail可以使导致锚tuple立即重发,而不用等到超时。每个tuple都应当被ack或fail,因为追踪每个tuple都是需要消耗内存的,最终导致OOM。BaseBasicBolt为每个输入tuple自动设锚,并在execute结束后自动ack tuple。没有被锚接到输入tuple 的流是不保证容错的。
使用redis list数据结构实现消息队列,可以在不同进程中分别使用 lpush 和 brpop之类,轻松实现ipc。
参考资料:
b1.《Getting started with storm 》