benchシナリオの要望が集まるissue
ToshihitoKon opened this issue · 22 comments
- 新規テナントはデータ量が軽くて回りやすいので、あんまり追加したくない
- 開催中の大会のplayerアクセスが多いはずなので、既存テナントの大会数が多いところのアクセスが集中して、新規テナントにはそこまでアクセスはない
- 初期データのbenchmarker.jsonはplayer数で偏って入ってるのでランダムに選べば偏るはず
- 新規テナントには既存データと同じくらいplayer入れてOK、BulkInsertで最初にドンと入れて残りは少しずつ
- 1つの新規テナントに大会->player->score->billing ...を繰り返すとvisitデータ量増えていく?
- 初期と同じく75visit per playerをリクエストで飛ばすのは難しい
- loadAdjustorは対象scenarioが一周していないと並列度を増やせないので、一周が遅いworkerに引っ張られて並列数が増えない
- 新規テナントがn個追加されたらその後、とかですね
- だんだん追加されるテナントがデカくなるとか
- 巨大団体が過去データを大量に引っ越ししてcsvがドカンとか
- セルフホストしてたのを移行してくるシナリオ
- ISUコングロマリット
ベンチ中のCSV入稿について
- CSVはおなじcompetitionに対しては常に後ろに追記される
- アプリケーション仕様的に後ろのほうのデータが新しい = ランキングに採用される
- 一人あたり平均100行ぐらいのデータが含まれている必要がある
- ISUCON開催中に100回ぐらいはベンチを回すはず
- ぴったり100回ではなくブレが欲しい
- CSV追記は入稿のたびに追記されてどんどん入稿されるデータが巨大になっていく
- 自動化されているのかほぼリアルタイムでCSVが入稿されていくシナリオ
- 失格シナリオはブン回す必要はない、あまり回しすぎるとプレイヤーが減りすぎる
- 初期データに関しては、heavy tenant(id=1), 非破壊的検証テナント(id=2~99から20個くらい), 不人気の破壊的並列化OKシナリオテナント(残り)で分けると良いかも
- player一覧APIは失格者も含めて返ってくる。初期データにはすべてvisit_historyがあるので、返ってきたプレイヤー数に100をかけるとbillingを確認できる
- admin billingはSaaS管理者向けなのでお客さん向けではないので遅くてもいいけど、tenant billingが遅いとtenantで大会が開かれない=playerも来ない=スコアが出ない、みたいなのがいいのかな organizerのresultとbillingを高速化しないとplayerが回らない、としたい
- admin billingを1 workerで見続ける、見終わったら1テナント増える
- tenantは大会を開催して終了して、billingが返ってきたら新規大会を作成する
- テナント管理者が大会追加
- 参加者が回る
の部分が同期的なので、ここも大会を追加したら参加者用のworkerを別に生やして、適宜秒数を散らしたsleepを入れながら複数人が同時アクセスするようにしたい
isucon12-qualify/bench/job_organizer.go
Lines 48 to 89 in 44c90e1
- 参加者はF5連打だけするわけではない
- ノータイム連打でスコアが上がりすぎる
- 参加者が動いている間テナント管理者が止まってしまう
- 複数人が同時に行動してロックを取り合ってほしい
参加者の行動パターン
現状だと一覧、player、rankingが1:1:1になるが、ブラウザの挙動を考えるとこんなふうになるはず
- /api/player/competitions で大会一覧を取る
- 一覧に含まれている大会を全てリクエスト /api/player/competition/*/ranking
- ranking上位のplayerをいくつかリクエスト /api/player/player/*
- 全ての大会でやる必要はなさそう
- 大会一覧は軽い + チューニングポイントではないので呼び出し回数は多くなくてよい
- ランキング閲覧は画面に表示される分、一気に取るはず
- playerはたまに気になった人を見るぐらい?
admin billingを高速化するとどんどん新規テナントが増える => 負荷がどんどん増える、のでここを調整できないと最終的にはサーバーがどんなに頑張っても耐えられない負荷を与えてしまう。
任意のAPIについて、429 Too Many Requestsを返してよい、という仕様を追加して、クライアントは Retry-After
ヘッダの秒数だけ次のリクエストまで待機する、という仕組みを入れたい。(同じリクエストをリトライするか、別のリクエストに進むかはシナリオ次第でよい)
PlayerHandlerのレスポンスをcacheして一度もpurgeしなくても通る -> validation追加が必要
PeacefulTenantScenarioで
- Playerを失格させる
- 失格プレイヤーで情報を見に行く -> 403を確認
としているが、この確認が /api/player/competitions のみ。playerやrankingのようなリクエストが多い(cacheしたい)エンドポイントで失格状態を見ていないので、不正にcacheされてしまう可能性がある。
最低限、player(他人)とranking(どれか適当に)を見に行って確認したい。
打ちきりになったときに、failしたよというのが分かるようにしたい。
スコアだけだと以下のように正の値が出ることがあり、この場合に完走してスコアが出たのか打ちきりでfailになったのかが判別できない(とポータルの表示で困るので)
09:42:54.688464 ERRORは最大30件まで表示しています
09:42:54.688997 SCORE: 82 (+402 -320)
打ちきりになったときに、failしたよというのが分かるようにしたい。
#155
resultSumがisPassedを返すようになりました
整合性チェックで静的ファイルをいくつか確認する
- nginxの設定をいじったりした場合に、うっかりstaticの配信を壊す可能性がある
- ベンチだけ掛けていると画面が壊れていることに気が付かなくて、目視チェックで失格する可能性がある
- そのような不幸をなくすため、 / (index.html) と css と js を一個ずつ取得して壊れてないかhash値をチェックする
- マニュアルにもHTMLとCSSとJSの内容は変更するなという記述があるか要確認
負荷走行中にはアクセスする必要はない
初期シナリオで tenant.id=1 に対して /api/organizer/billing が5分かかる (on EC2)
[00] {"time":"2022-07-18T04:35:11.992840274Z","level":"ERROR","prefix":"echo","file":"isuports.go","line":"194","message":"error at /api/organizer/billing: write tcp 127.0.0.1:3000->127.0.0.1:36794: write: broken pipe"}
[00] {"time":"2022-07-18T04:35:11.992877566Z","id":"","remote_ip":"127.0.0.1","host":"isucon.t.isucon.dev","method":"GET","uri":"/api/organizer/billing","user_agent":"isucandar","status":500,"error":"write tcp 127.0.0.1:3000-\u003e127.0.0.1:36794: write: broken pipe","latency":281267359570,"latency_human":"4m41.26735957s","bytes_in":0,"bytes_out":3993}
"latency_human":"4m41.26735957s"
ベンチが終わってもサーバー側の処理は終わらないので、延々とMySQLがクエリを実行し続ける状態になり、これを何も知らない状態で見ると大変困惑するはず。
どうにかする方法(案)
- tenant.id=1 のボリュームをもうちょっと加減する?
- API実行に適当にタイムアウトを設ける
- Goだと用意だけどPerlみたいなシングルプロセスモデルだと結構面倒くさい
- admin billing を一周するまでは tenant.id=1 のシナリオは走らせない
- admin billing が一周できるなら organizer billing も問題ないはずなので
admin billing を一周するまでは tenant.id=1 のシナリオは走らせない
なるほど
admin billingはid=1も含めて全部回して、それが終わるまでPopularTenantHeavyを発火させない形ですよね、benchで対応出来るものとしてはこれが良さそうなので入れます
レスポンスに変更が無い場合は304 not modifiedを許容する
- score、disqualifyが実行されない限りそのテナントについては問題なし
- admin billing、対象範囲のテナントに操作が無ければ304返してもヨシ
JWT鍵確認
- 違う秘密鍵
- 違う鍵方式
#190
PlayerValidateがスッカスカかもしれない
エラーメッセージ、常にアクセス先のvhostを出してほしい。