我已经实现了我的第一个GridGain应用程序,但是并没有获得预期的性能改进。可悲的是它比较慢。我需要一些改进实施的帮助,以便更快地进行。

我的应用程序的要旨是,我正在使用数以百万计的可能参数进行蛮力优化,每个函数评估需要花费一秒钟的时间。我通过将数百万次迭代分成几组来实现这一点,并且每一组都作为一个作业执行。

相关代码如下。函数maxAppliedRange为范围x中的每个值调用函数foo,并返回最大值,结果变为每个作业找到的所有最大值中的最大值。

  scalar {
    result = grid !*~
      (for (x <- (1 to threads).map(i => ((i - 1) * iterations / threads, i * iterations / threads)))
        yield () => maxAppliedRange(x, foo), (s: Seq[(Double, Long)]) => s.max)
  }

我的代码可以在一台机器上的多线程执行之间进行选择,也可以使用上面的代码使用多个GridGain节点。当我运行gridgain版本时,它开始的速度似乎会更快,但是总会发生一些事情:
  • (在另一台计算机上)节点中的一个节点丢失心跳,导致我的主计算机上的节点放弃该节点并再次开始执行作业。
  • 丢失心跳的节点将继续执行相同的工作。现在,我有两个节点在做同一件事。
  • 最终,所有作业都在我的主机上执行,但是由于某些作业是在以后启动的,因此完成所有工作都需要更长的时间。
  • 有时,由于节点超时并且整个任务失败,GridGain会引发异常。
  • 我很生气。

  • 我尝试将其设置为具有许多作业,因此,如果一个作业失败,那么就没什么大不了的,但是当我这样做时,我最终会在每个节点上执行许多作业。这给每台机器带来了更大的负担,从而使节点更有可能错过心跳,从而导致一切下坡速度更快。如果每个CPU有一个作业,那么如果一个作业失败,则必须从头开始重新启动另一个节点。无论哪种方式,我都无法赢。

    我认为最好的方法是可以做两件事:
  • 增加心跳超时
  • 限制每个节点,使其一次仅执行一项工作。

  • 如果可以这样做,我可以将我的任务分为许多工作。每个节点一次只能完成一项工作,并且任何机器都不会因负担过多而丢失心跳。如果一项工作失败了,那么几乎不会有任何工作,并且恢复很快。

    谁能告诉我该怎么做?我应该在这里做什么?

    最佳答案

    我想到了。

    首先,有一个xml配置文件,用于控制网格节点如何操作的详细信息。默认配置文件在GRIDGAIN_HOME / config / default-spring.xml中。启动网格节点时,我可以对其进行编辑或复制,然后将新文件传递给ggstart.sh。我需要添加的两件事是:

        <property name="networkTimeout" value="25000"/>
    

    将网络消息的超时设置为25秒,并且
       <property name="executorService">
            <bean class="org.gridgain.grid.thread.GridThreadPoolExecutor">
                <constructor-arg type="int" value="1"/>
                <constructor-arg type="int" value="1"/>
                <constructor-arg type="long">
                    <util:constant static-field="java.lang.Long.MAX_VALUE"/>
                </constructor-arg>
                <constructor-arg type="java.util.concurrent.BlockingQueue">
                    <bean class="java.util.concurrent.LinkedBlockingQueue"/>
                </constructor-arg>
            </bean>
        </property>
    

    前两个构造函数参数用于启动1个线程,最大线程大小为1。执行程序服务控制执行gridgain作业的线程池。默认值为100,这就是为什么我的应用程序不堪重负且心跳超时的原因。

    我必须对代码进行的其他更改是:
      scalar.apply("/path/to/gridgain home/config/custom-spring.xml") {
        result = grid !*~
          (for (x <- (1 to threads).map(i => ((i - 1) * iterations / threads, i * iterations / threads)))
            yield () => maxAppliedRange(x, kalmanBruteForceObj.performKalmanIteration), (s: Seq[(Double, Long)]) => s.max)
      }
    

    因为没有.apply语句,它将启动具有所有默认选项的网格节点,而不是具有上述编辑的配置文件,这正是我想要的。

    现在,它完全可以按照我的需要工作了。我可以将任务分为几部分,即使我最弱和最慢的计算机也可以为这项工作做出贡献。

    关于scala - 在一台机器上比多线程应用程序慢的GridGain应用程序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4481645/

    10-10 11:27