我看到许多代码片段中使用了循环 Spout.nextTuple()
(例如,读取整个文件并为每行发出一个元组):
public void nextTuple() {
// do other stuff here
// reader might be BufferedReader that is initialized in open()
String str;
while((str = reader.readLine()) != null) {
_collector.emit(new Values(str));
}
// do some more stuff here
}
这个代码似乎是直截了当的,但是,我被告知,一个不应该循环内 nextTuple()
. 问题是为什么?
1条答案
按热度按时间bvjxkvbb1#
当一个喷口被执行时,它在一个线程中运行。此线程“永远”循环并具有多个职责:
呼叫
Spout.nextTuple()
检索“ack”并处理它们检索“失败”并处理它们
超时元组
要做到这一点,重要的是,你不要停留在“永远”(即循环或块)中
nextTuple()
但是在向系统发出一个元组后返回(或者如果不能发出元组,则返回,但不要阻塞)。否则,喷口不能正常工作。nextTuple()
将在Storm中循环调用。因此,在处理ack/fail消息等之后,下一次调用nextTuple()
发生得很快。因此,在一次调用中发出多个元组也被认为是不好的做法
nextTuple()
. 只要代码还在nextTuple()
,喷口线程不能(例如)对传入的ack作出React。这可能会导致不必要的超时,因为无法及时处理ack。最佳实践是为每个调用发出一个元组
nextTuple()
. 如果没有可发射的元组,则应返回(不发射),而不要等到元组可用时才返回。