【问题标题】:Should Storm spouts sleep() or yield()?Storm 应该喷出 sleep() 还是 yield()?
【发布时间】:2018-07-17 12:55:11
【问题描述】:

nextTuple() 的 Storm 文档说明如下:

当没有要发出的元组时,最好让 nextTuple 休眠一小段时间(比如一毫秒),以免浪费太多 CPU。

Utils.class 中似乎有一种方法:Utils.sleep(long millis)

但是,在 Apache Storm 本身提供的一个 spout 中,MqttSpout 使用了不同的方法:

public void nextTuple() {
    AckableMessage tm = this.incoming.poll();
    if(tm != null){
        ...
    } else {
        Thread.yield();
    }
}

我怀疑 Storm 作者可能在那里犯了一个错误,因为 Thread.yield() 本身在文档中有以下注释:

向调度程序提示当前线程愿意让出其当前使用的处理器。调度程序可以随意忽略此提示。

这种方法很少适用。

那么我应该使用哪一个?我怀疑使用 Thread.yield() 会导致不必要的 CPU 使用。

【问题讨论】:

    标签: concurrency apache-storm thread-sleep


    【解决方案1】:

    您的喷口根本不应该休眠。如果您在通话期间不发出任何内容,Storm 将处理对 nextTuple 的调用之间的睡眠,至少在我熟悉的版本中,即 1.0.0 及更高版本。

    请参阅https://github.com/apache/storm/blob/v1.2.2/storm-core/src/clj/org/apache/storm/daemon/executor.clj#L667 以供参考。等待策略的默认实现在每次调用时都会休眠一段可配置的时间间隔(默认为 1ms)。您可以使用https://github.com/apache/storm/blob/v1.2.2/storm-core/src/jvm/org/apache/storm/Config.java#L1886 控制间隔或将等待策略完全替换为https://github.com/apache/storm/blob/v1.2.2/storm-core/src/jvm/org/apache/storm/Config.java#L1879

    Storm 2.0.0 的行为略有不同(睡眠时间逐渐延长),但基本理念相同。

    我认为 nextTuple 的 javadoc 具有误导性,所以我们应该修改它。我也不确定 Thread.yield 在 mqtt spout 中做了什么。自从添加了喷口以来,它似乎一直存在。如果您在其中一个邮件列表 (https://storm.apache.org/getting-help.html) 上提问,作者仍然在附近,并且可能知道它为什么在那里。

    如果您愿意,可以在https://issues.apache.org/jira/secure/Dashboard.jspa 提出问题来解决这个问题:)

    【讨论】:

    • 感谢您的回答,我想知道如果没有要发出的元组,为什么 Storm 会占用 CPU,所以这可能只是早期版本或类似版本的工件是有道理的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-02
    • 2013-11-11
    • 2015-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多