Naoki Kurosawa
naoki_kuros****@ybb*****
2003年 3月 31日 (月) 15:35:53 JST
黒澤です。 スループットの表示についてです。 今のところ私が考えているのは、 ■トップページ 現在オンライン中の分散サーバの台数と、 毎分or毎時の実行ラウンド数→システム全体のスループット ■スループット詳細ページ 分散サーバの一覧 表示内容: ・オンライン中か否か ・平均スループット(毎分or毎時の実行ラウンド数 or 1ラウンドにかかる時間) ・トータル実行ラウンド数 システム全体のスループット履歴 表示内容:例えば1時間ごとの、 ・オンラインサーバ数 ・毎分or毎時の実行ラウンド数 を時系列で表示 表示に使うデータはmachinesテーブルに、 machine_id 分散サーバのID user_id 分散サーバの持ち主のユーザID hostname ホスト名 password 中央サーバにアクセスするときのパスワード last_posted 最終アクセス日時 duel_exec_rounds 1on1の総実行ラウンド数 duel_time_total 1on1の総実行時間 duel_time_max 1on1の1ラウンドにかかった時間の最大値 duel_recent_time 1on1の1ラウンドにかかった時間の直近値 melee_exec_rounds meleeの総実行ラウンド数 melee_time_total meleeの総実行時間 melee_time_max meleeの1ラウンドにかかった時間の最大値 melee_recent_time meleeの1ラウンドにかかった時間の直近値 communication_count 通信回数 communication_time_total 総通信時間 communication_time_max 1回の通信にかかった時間の最大値 という形で保持されています。 1on1およびmeleeの実行時間については、分散サーバ側で計測し、 BattleResultオブジェクトに入れて送信しているので、 純粋なBattle実行時間です。 表示内容の計算方法としては ■スループット履歴の計算 1時間間隔の履歴を作ると仮定して…。 まず、スループット履歴を保持するテーブルを作ります。 たとえば、 create table throughput ( record_date datetime not null, -- 記録時刻 active_servers int not null, -- オンラインの分散サーバ数 exec_rounds int not null, -- 前回の記録からの -- 実行ラウンド数 primary key (record_date) ) type = InnoDB; こんな感じ。 battleobserver.jarのように定期的に起動されるクラスを作り、 毎時0分のタイミングで、その過去1時間内にアクセスのあった (last_postedの時刻が現在から1時間前までに入る)マシンを オンラインの分散サーバとしてカウントします。 select count(*) from machines where last_posted >= ?1 - interval 1 hour and last_posted < ?1 ※?1には現在時刻が入る 同じタイミングで、 過去1時間以内に完了したバトルのラウンド数を集計します。 select sum(leagues.rounds) from leagues, battles where leagues.league_id = battles.league_id and battles.finish_date >= ?1 - interval 1 hour and battles.finish_date < ?1 で、throughputテーブルに、 insert into throughput values (?1, <machine count>, <round count>); します。 この処理を行うタイミングでサーバが落ちてたりするとあれだなと思うので、 select record_date from throughput order by record_date desc limit 1 とかやって最後に記録した日時を取得して、そこから1時間以上経っていたら、 1時間ずつ足しながら繰り返し上記の処理を実行するようにした方が いいですね。 ただ、これだとthroughputテーブルにデータがまったく存在しないときに エラーになってしまうので、最初に1行だけダミーデータを入れておく 必要があります。 ■スループット表示 DistServerManagerBeanにメソッド追加 ○getTotalThroughput select * from throughput order by record_date desc limit 1 とやって、最新のスループット情報を取得する。 ○getThroughputHistory 最近1週間のスループット情報を時系列で取得する。 ○getDistServers machinesテーブルから分散サーバ一覧を取得 オンラインか否か、1on1とmeleeそれぞれの実行スループット(何ラウンド毎時) が含まれる。 過去1時間以内にアクセスのあった分散サーバはオンラインと判断。 スループットについては、 duel_exec_rounds 1on1の総実行ラウンド数 duel_time_total 1on1の総実行時間 melee_exec_rounds meleeの総実行ラウンド数 melee_time_total meleeの総実行時間 を用いて平均値を表示するか、 duel_recent_time 1on1の1ラウンドにかかった時間の直近値 melee_recent_time meleeの1ラウンドにかかった時間の直近値 を使って直近値を表示するかは悩みどころ。 という流れでの開発となると思います。 ------------------------------ 補足: machinesテーブルの通信時間 というところは以下のようにして計測しています。 通信方向 分散←→中央 1.分散サーバが中央サーバにバトルを要求 → 2.中央サーバがlast_postedに現在時刻を書き込み ┐ 3.中央サーバから分散サーバにバトル情報転送 ← │ 4.バトル実行 │ 5.分散サーバが実行結果を中央サーバに転送 → │ ┘ 6.last_postedと現在時刻の時間差からバトル実行時間を引いて 通信時間を計算 7.中央サーバがlast_postedに現在時刻を書き込み ┐ 8.中央サーバから分散サーバにバトル情報転送 ← │ ... と続く通信の中で、鍵括弧した範囲の通信時間を計測します。 中央サーバ上でのDB読み書きの時間も通信時間として カウントされています。→DB読み書きと通信は区別した方がいいかな? 計測範囲内に上り1回、下り1回の通信が含まれているので、 通信時間の最大値は1往復分の値の最大値です。 一番最初の分散サーバからのリクエストと、 一番最後の中央サーバからのレスポンスがカウントされないので、 通信回数フィールドは実際の通信回数より少々少なくなります。 ------------------------------ -- Naoki Kurosawa <naoki_kuros****@ybb*****>