最初のGridGainアプリケーションを実装しましたが、期待したパフォーマンスの向上が得られません。悲しいことに、それは遅いです。より速くできるように、実装を改善するための助けが欲しいです。
私のアプリケーションの要点は、関数の評価ごとに数分の1秒かかる数百万の可能なパラメーターを使用して力ずくの最適化を行っていることです。私はこれを、数百万の反復をいくつかのグループに分割することによって実装しました。各グループは1つのジョブとして実行されます。
関連するコードは以下のとおりです。関数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)
}
私のコードは、1台のマシンでマルチスレッド実行するか、上記のコードを使用して複数のGridGainノードを使用するかを選択できます。gridgainバージョンを実行すると、最初は高速になるように見えますが、その後は常にいくつかのことが起こります。
- (別のマシン上の)ノードの1つがハートビートを逃し、メインコンピューター上のノードがそのノードをあきらめて、ジョブの実行を2回開始します。
- ハートビートを逃したノードは、同じ仕事を続けます。これで、2つのノードが同じことを実行します。
- 最終的には、すべてのジョブがメインマシンで実行されますが、一部のジョブは後で開始されるため、すべてが完了するまでに時間がかかります。
- ノードがタイムアウトし、タスク全体が失敗したために、GridGainによって例外がスローされることがあります。
- イライラします。
多くのジョブを持つように設定してみたので、1つが失敗してもそれほど大きな問題にはなりませんが、これを行うと、各ノードで多くのジョブが実行されることになります。これにより、各マシンに非常に大きな負担がかかり、ノードがハートビートを見逃す可能性が高くなり、すべてがより速く下り坂になります。CPUごとに1つのジョブがある場合、1つのジョブが失敗すると、別のノードを最初からやり直す必要があります。いずれにせよ、私は勝つことができません。
私が最もうまくいくと思うのは、2つのことができるかどうかです。
- ハートビートのタイムアウトを増やす
- 一度に1つのジョブのみを実行するように、各ノードをスロットルします。
これができれば、自分の仕事を多くの仕事に分割することができます。各ノードは一度に1つのジョブを実行し、マシンが過負荷になってハートビートを逃すことはありません。ジョブが失敗した場合、ほとんど作業が失われず、回復は迅速になります。
誰かがこれを行う方法を教えてもらえますか?私はここで何をすべきですか?