スケジューラ RPC タイミングと再試行ポリシー |
![]() Last modified 7:09 PM UTC, June 09 2004 |
個々のスケジューラ RPCでは、結果を報告したり、 仕事を受取ったり、あるいは両方を同時に行っています。 クライアントのスケジューラ RPC ポリシーには、 いくつかの構成要素が含まれています。 それらは、 いつスケジューラ RPC を出すか、 どのプロジェクトに繋ぐのか、 そのプロジェクトのどのスケジューリング・サーバを選ぶのか、 どのくらいの大きさの仕事を求めるのか、 そして、もし RPC が失敗したらどうするのか、といったことです。
スケジューラ RPC ポリシーには、以下の目標があります。
クライアントでは、各プロジェクトごとに捧げられた CPU時間の合計値を、指数関数的重みづけをした平均(exp_avg_cpu)として、 維持管理しています。 定数 EXP_DECAY_RATE が、[指数関数的重みづけの]低減率です。 (現在、この値は、毎週ごとに e(自然対数底)の低減率です。 )
各プロジェクトは、下記のように計算された 資源の負債 (resource_debt)を割り当てられます。
resource_debt = resource_share / exp_avg_cpu
(資源の負債)=(資源占有率) / (指数関数的重みづけをした平均CPU消費時間)
ここで、'exp_avg_cpu' は、最近そのプロジェクトで消費した CPU 時間です(指数関数的重みづけをした平均値)。 資源の負債は、そのクライアントが そのプロジェクトにどれだけの仕事をする責務があるかを示す 指標です。 ですから、一般的には、最大の資源の負債をもつプロジェクトから、 仕事を要求するべきです。
クライアントは、プロジェクトごとに最短 RPC 時刻(min_rpc_time) 訳注2 を管理しています。 これは、そのプロジェクトに対して スケジューリング RPC を実行するべき 最も早い時刻です。 (もし値が0ならば、RPC を今すぐ行って良いという意味に なります。 ) 最短 RPC 時刻 は、以下のような色々な理由から値が決まります。
スケジューラとの通信は、セションという形に 組織化されます。 それぞれのセションには、たくさんの RPCが含まれます。 セションには2つの型があります。
get_work_session() { while (仕事の推定完了時刻 < 高ウォーターマーク) P = (最短RPC時刻<現在時刻 のプロジェクトの中で 最大の「資源の負債」をもつもの) for each 上記Pのスケジューラ URLについて RPC をそのURLについて1度試す if エラーなしなら break if RPCがどれか成功していたら P.nrpc_failures = 0 //RPC失敗回数=0 else P.nrpc_failures++ //RPC失敗回数++ P.min_rpc_time = exponential_backoff(P.min_rpc_failures) //指数バックオフで次回のRPC可能時刻を決める if P.nrpc_failures mod MASTER_FETCH_PERIOD = 0 P.fetch_master_flag = true // 失敗が続くと、MASTER_FETCH_PERIODの回数おきに //マスターURLをチェックしに行く。 for each プロジェクト(その fetch_master_flag がたっているもの) マスターファイルを読んで解析する if エラーがおきたら P.nrpc_failures++ //RPC失敗回数++ P.min_rpc_time = exponential_backoff(P.min_rpc_failures) //指数バックオフで次回のRPC可能時刻を決める if 新しいスケジューラのURLが一つでもえられたら、 P.nrpc_failures = 0 //RPC失敗回数と最短RPC時刻を0にリセット P.min_rpc_time = 0 } report_result_session(project P) { for each プロジェクトPのそれぞれのスケジューラ URL について RPC をそのURLについて1度試す if エラーなしなら break if RPCがどれか成功していたら P.nrpc_failures = 0 //RPC失敗回数=0 else P.nrpc_failures++; //RPC失敗回数++ P.min_rpc_time = exponential_backoff(P.min_rpc_failures) //指数バックオフで次回のRPC可能時刻を決める }スケジューラ・セションを起動する論理は、 scheduler_rpcs->poll() という関数で 実現されています。
if スケジューラ RPC セションが生きていなければ、 if (仕事の推定完了時刻 < 低ウォーターマーク) 仕事の受取りセション(get-work)を開始させる。 else if 期限を過ぎた計算結果をどれかのプロジェクトPがもっていれば 結果の報告セション(report-result)をPのために開始する。 if P が最大の「資源の負債」をもつプロジェクトであるなら、 その RPC 要求は 高ウォーターマークより高いところまで、 充分な仕事を求めるべきである。