为什么不在spout.nexttuple()中循环或阻塞

eqoofvh9  于 2021-06-21  发布在  Storm
关注(0)|答案(1)|浏览(247)

我看到许多代码片段中使用了循环 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() . 问题是为什么?

bvjxkvbb

bvjxkvbb1#

当一个喷口被执行时,它在一个线程中运行。此线程“永远”循环并具有多个职责:
呼叫 Spout.nextTuple() 检索“ack”并处理它们
检索“失败”并处理它们
超时元组
要做到这一点,重要的是,你不要停留在“永远”(即循环或块)中 nextTuple() 但是在向系统发出一个元组后返回(或者如果不能发出元组,则返回,但不要阻塞)。否则,喷口不能正常工作。 nextTuple() 将在Storm中循环调用。因此,在处理ack/fail消息等之后,下一次调用 nextTuple() 发生得很快。
因此,在一次调用中发出多个元组也被认为是不好的做法 nextTuple() . 只要代码还在 nextTuple() ,喷口线程不能(例如)对传入的ack作出React。这可能会导致不必要的超时,因为无法及时处理ack。
最佳实践是为每个调用发出一个元组 nextTuple() . 如果没有可发射的元组,则应返回(不发射),而不要等到元组可用时才返回。

相关问题