【问题标题】:Why should I not loop or block in Spout.nextTuple()为什么我不应该在 Spout.nextTuple() 中循环或阻塞
【发布时间】:2015-12-09 11:01:16
【问题描述】:

我看到很多代码 sn-ps 在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()循环。问题是为什么?

【问题讨论】:

    标签: apache-storm


    【解决方案1】:

    当一个 Spout 被执行时,它在一个线程中运行。该线程“永远”循环并具有多种职责:

    1. 致电Spout.nextTuple()
    2. 检索“ack”并处理它们
    3. 检索“失败”并处理它们
    4. 超时元组

    为此,您不能“永远”停留在nextTuple() 中(即循环或阻塞),而是在向系统发出元组后返回(或者如果无法发出元组,则直接返回) ,但不要阻止)。否则,Spout 无法正常工作。 nextTuple() 将被 Storm 循环调用。因此,在处理完 ack/fail 消息等之后,对nextTuple() 的下一次调用会很快发生。

    因此,在对nextTuple() 的一次调用中发出多个元组也被认为是不好的做法。只要代码保留在nextTuple() 中,spout 线程就不能(例如)对传入的确认作出反应。这可能会导致不必要的超时,因为无法及时处理确认。

    最佳做法是为每次调用nextTuple() 发出一个元组。如果没有可发出的元组,您应该返回(不发出)并且不要等到元组可用。

    【讨论】:

      猜你喜欢
      • 2019-02-18
      • 2016-04-21
      • 1970-01-01
      • 1970-01-01
      • 2012-12-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多