Upgrade to Pro — share decks privately, control downloads, hide ads and more …

190905_スマホゲームリリース時に絶対サーバを落とさないための負荷試験.pdf

Cygames
September 05, 2019

 190905_スマホゲームリリース時に絶対サーバを落とさないための負荷試験.pdf

2019/09/05 CEDEC 2019

Cygames

September 05, 2019
Tweet

More Decks by Cygames

Other Decks in Technology

Transcript

  1. 自己紹介 3/85 Ito Eichi 伊藤 英知 Cygames 技術本部コンシューマー シニアエンジニア 主にサーバ周り担当

    社内の負荷試験・負荷対策に関わる 最近ではミドルウェアの検証や社内のPHP フレームワークのメンテナンス・PHPのエ クステンション作成等を行う 負荷かけるのとチューニングするのが好き
  2. はじめに 9/85 ルール2: 計測すべし。計測するまでは速度のための調整を してはならない。コードの一部が残りを圧倒しないのであ れば、なおさらである。 Rule 2. Measure. Don't

    tune for speed until you've measured, and even then don't unless one part of the code overwhelms the rest. by Rob Pike 出典 https://ja.wikipedia.org/wiki/UNIX哲学 計測の重要性 ” “
  3. 15/85 • 負荷試験のポイント • 想定アクセス数の決め方 • 負荷のかけ方 • 計測項目のリストアップ •

    計測用ツールの準備 • ツールの使い分け • 負荷試験対象の優先度を決める • 負荷試験環境の構築のポイント 絶対サーバを落とさない負荷試験
  4. 16/85 • 負荷試験のポイント • 想定アクセス数の決め方 • 負荷のかけ方 • 計測項目のリストアップ •

    計測用ツールの準備 • ツールの使い分け • 負荷試験対象の優先度を決める • 負荷試験環境の構築のポイント 絶対サーバを落とさない負荷試験
  5. 20/85 • 想定以上にユーザーのアクセスが集中した ➡アクセス数の見積もりが間違っていた (正しく見積もれていない) • DBやキャッシュの負荷が上がりサーバが落ちた ➡負荷試験で仕様の最大値テストをしていなかった (限界値を見つけてられていない) •

    サーバが落ちてないのに実際アクセスするとエラー ➡計測項目の不足 (ボトルネックを見つけられていない) 現象から考えられる原因 絶対サーバを落とさない負荷試験 負荷試験のポイント
  6. 21/85 • 負荷試験のポイント • 想定アクセス数の決め方 • 負荷のかけ方 • 計測項目のリストアップ •

    計測用ツールの準備 • ツールの使い分け • 負荷試験対象の優先度を決める • 負荷試験環境の構築のポイント 絶対サーバを落とさない負荷試験
  7. 運用中タイトルの測定値を集めておく リリース直後等アクセス集中時の下記項目を記録 継続的に複数タイトルのデータを集めると傾向がわかる • DAU(Daily Active User) • HAU(Hourly Active

    User) アクセス数の推定には直接は不要だが集中度合いを比較しやすい • MiAU(Minutely Active User) • 1ユーザ当たり分間アクセス数 • スループット[req/sec] 24/85 想定アクセス数の決め方 運用中タイトルの測定値を集めておく
  8. 運用中タイトルの測定値を集めておく 下記の式で想定DAUからアクセス数の予想材料にする 25/85 スループット[req/sec] = 想定DAU * 1分間集中率 * 1ユーザ当たり分間アクセス数

    / 60 アクセス集中したときの MiAU/DAU比率 テストプレイ中の 開発サーバのログ等から測定 想定アクセス数の決め方 運用中タイトルの測定値を集めておく
  9. 安全率を2.0以上とる 26/85 安全率 = 限界性能[req/sec] / 想定アクセス[req/sec] 「安全率」とは…限界性能に対する余裕度 例: 想定スループット数3000[req/sec]に対して

    限界性能6000[req/sec]のサーバを用意した場合 6000/3000 = 安全率2.0 負荷試験での 限界値測定結果 アクセス数 見積もりの値 想定アクセス数の決め方 安全率を2.0以上とる
  10. 30/85 • 負荷試験のポイント • 想定アクセス数の決め方 • 負荷のかけ方 • 計測項目のリストアップ •

    計測用ツールの準備 • ツールの使い分け • 負荷試験対象の優先度を決める • 負荷試験環境の構築のポイント 絶対サーバを落とさない負荷試験
  11. 32/85 • 負荷試験のポイント • 想定アクセス数の決め方 • 負荷のかけ方 • 計測項目のリストアップ •

    計測用ツールの準備 • ツールの使い分け • 負荷試験対象の優先度を決める • 負荷試験環境の構築のポイント 絶対サーバを落とさない負荷試験
  12. 33/85 サーバが落ちないよう多角的に計測項目を設定する • 計測項目の意味を理解する ・ memcached のUnfetched Evictionはどういうときに出るのか? ・ Time

    WaitなどTCPの各ステータスがどんなときに上昇するか? …等 • 負荷の計測手段を複数用意する ・得意分野が違うのでプロファイラと監視ツール最低限各1つは あった方が良い。 例: mackerelとnewrelic (後述) • 運用中の負荷を普段からよく見ておく ・特に最初に異常を示し始める計測項目を知っておく 計測項目のリストアップ 絶対サーバを落とさない負荷試験
  13. • PHP Idle Worker • MySQL Row Lock Time, Slow

    Query, Abort Client, Slave status • Memcached Unfetched Eviction, Hit/Miss率 • Redis Evictions, CPU1コア毎の使用率, Hit/Miss率 34/85 • Node.js Context switch, CPU1コア毎使用率 • Linux全般 Time Wait, File Descriptor, Disk Latency, Free Storage, Inode, Traffic • LB HTTP Code Count etc... 負荷試験中によく使うメトリクスの例 絶対サーバを落とさない負荷試験 計測項目のリストアップ
  14. 35/85 一見CPU使用率は正常… CPU 使用率 Worker Process 使用率 全Worker Processが Busyに!

    リクエスト受付不可能 な状態 計測項目のリストアップ 絶対サーバを落とさない負荷試験
  15. 36/85 • 負荷試験のポイント • 想定アクセス数の決め方 • 負荷のかけ方 • 計測項目のリストアップ •

    計測用ツールの準備 • ツールの使い分け • 負荷試験対象の優先度を決める • 負荷試験環境の構築のポイント 絶対サーバを落とさない負荷試験
  16. 監視/計測用ツールの準備 38/85 • 監視ツール系 Mackerel Datadog ※APMも有 Munin Cloud Watch

    top sar vmstat kibana • プロファイラ系 各種言語対応 Newrelic ※監視機能も有 PHP Tideways(Xhprof) xdebug(Valgrind系) C/C++ Vtune Amplifier , gperf, Valgrind Node.js Node-Inspect(inspectオプション) etc... ミドルウェア・得意分野に応じて適切なものを選択 絶対サーバを落とさない負荷試験 計測用ツールの準備
  17. 39/85 • 負荷試験のポイント • 想定アクセス数の決め方 • 負荷のかけ方 • 計測項目のリストアップ •

    計測用ツールの準備 • ツールの使い分け • 負荷試験対象の優先度を決める • 負荷試験環境の構築のポイント 絶対サーバを落とさない負荷試験
  18. 40/85 • JMeter 主にHTTP(s)の負荷試験向き • Mocha+ダミークライアント 主にSocket.IOの負荷試験・外形テスト向き • C#製自作ツール TCP/UDPの負荷試験向き

    • Vegeta-mysql MySQLのチューニング・性能比較向き 向き不向きがあるので複数使う(作る) 絶対サーバを落とさない負荷試験 ツールの使い分け
  19. • 使用したケース ・ゲームタイトルの公式ページの負荷試験 ・ブラウザアクセスのproxyとしてJMeterの HTTP(S) Test Script Recorderを指定しリクエストを記録。 これを負荷シナリオとして再編集。 ・

    HTTP(S)のみのゲームAPIの負荷試験 ・シリアライズ・暗号化等含めたバイナリのBodyをリクエスト カスタマイズしたHTTP Samplerを作成して負荷試験 42/85 JMeter ツールの使い分け
  20. describe('クエスト開始準備', () => { it('ホストからメッセージ送信', () => { const promises

    = []; promises.push(host.waitForEmitAndAssert(define.EVENT .QUEST , define.URI.READY)); promises.push(guest1.waitForEmitAndAssert(define.EVENT .QUEST , define.URI.READY)); promises.push(guest2.waitForEmitAndAssert(define.EVENT .QUEST , define.URI.READY)); promises.push(host.emitAndAssertAll(define.EVENT .QUEST , define.URI.WAVE_READY , { 'ready_state': define.READY_STATE.QUEST_START , 'frame': 0 }, guest1, guest2)); return Promise.all(promises); }); }); 44/85 Mocha負荷シナリオの例 メッセージイベント 待ち受け メッセージ送信 ツールの使い分け mocha+ダミークライアント
  21. await Connect();// 前処理 await SendSignup();// ユーザ登録 await SendTutorial();// チュートリアル await

    SendMyPage();// マイページアクセス // 10回クエストを行う for (var i = 10; i < 10; ++i) { await SendQuestStart();// クエストスタート await Wait(500);// 500ms待ち await SendQuestFinish();// クエスト終了 } await Disconnect(); Stop();// 後処理 47/85 awaitで非同期の処理を 簡潔に記述 CSX負荷シナリオの例 ループ回数・処理順等 挙動の変更が容易 ツールの使い分け C#自作ツール
  22. Vegeta-mysql 48/85 • 特徴 ・Go製 ・パフォーマンス高い ・DBの負荷だけ測りたい時に便利 ・テキストファイルに投げたいクエリのリストを記載して使う vegeta-mysql attack

    -dsn “user:pass@tcp(localhost:3306)/dbname” -body sql.txt ¥ -duration=60s | tee results.bin | vegeta-mysql report 負荷試験で投げたい SQLのリスト ツールの使い分け
  23. 50/85 • 負荷試験のポイント • 想定アクセス数の決め方 • 負荷のかけ方 • 計測項目のリストアップ •

    計測用ツールの準備 • ツールの使い分け • 負荷試験対象の優先度を決める • 負荷試験環境の構築のポイント 絶対サーバを落とさない負荷試験
  24. 51/85 負荷試験対象の優先度を決める • 優先すべき箇所の分類 1. 全ユーザーが必ずリクエストする箇所 2. リクエストされる頻度が高い箇所 • APIごとのアクセス回数の調査方法

    パラメータの組み合わせを含めたうえですべてのAPIを負荷試 験できるケースは少ない 限られた負荷試験期間で致命的なボトルネックを探す 絶対サーバを落とさない負荷試験 負荷試験対象の優先度を決める
  25. 57/85 • APIごとのアクセス回数の調査方法 どのAPIがどれくらいアクセスされているかを集計 • 方法(1) Newrelicのツールの統計機能を使う 合計レスポンスタイムもわかるので便利 ’Transactions’->’Show all

    transactions table…’で表示できる • 方法(2) KibanaのVisualizeで集計する ログの取り込みや設置の手間はかかるが 不具合調査に利用でき、カスタマイズ性も高い。 平均レスポンスサイズも合わせて集計するのがおすすめ 負荷試験対象の優先度を決める
  26. 58/85 • 負荷試験のポイント • 想定アクセス数の決め方 • 負荷のかけ方 • 計測項目のリストアップ •

    計測用ツールの準備 • ツールの使い分け • 負荷試験対象の優先度を決める • 負荷試験環境の構築のポイント 絶対サーバを落とさない負荷試験
  27. 60/85 • 開発中に目標値が上方修正されることがある 事前登録の伸び リリースするリージョンの増加 • 限界値を測定しているとかけ元サーバが足りなくなる 安全率の想定の変更 負荷かけ元サーバ台数もコンテナ合わせて1000台以上必要な時も 例:

    Socketの60万同時接続, APIアクセス10万rps以上を再現する チューニングの進展 開発プロジェクトの状況の変化への素早い対応が必要 負荷かけ元のスケールアウトが必要な理由 負荷試験環境の構築のポイント
  28. 61/85 負荷試験環境の構築のポイント 各種負荷ツールを インストール済み のAMI AWS のAPIをコール 任意のAMIから EC2インスタンス作成 このインスタンス群から

    負荷をかける EC2 * N台 大量にインスタンスを立てるの で、インスタンス管理をしっか りする必要がある インスタンス 作成完了時 Slackに通知
  29. 63/85 • Spot Instanceの利点 ・安い ・基本的にEC2と同様の動作 • Spot Instanceの欠点 ・価格が変動することがある

    ・起動し続ける保証はない ・インスタンスを自分で作成・管理・破棄する必要がある Spot Instanceの作成・管理・破棄の システムを作ることで欠点を補う 大量の負荷かけ元サーバの管理 負荷試験環境の構築のポイント
  30. 64/85 • コストの差 Spot Instance $0.0675 /時間 On demand Instance

    $0.214 /時間 -0.05 0.05 0.15 0.25 1 2 3 4 5 6 7 8 Ondemand Instance -0.05 0.05 0.15 0.25 1 2 3 4 5 6 7 8 Spot Instance 正味の負荷試験時しか コストが発生しない 時間あたりでも 値段が約1/3 ※c5.xlarge , 2019年8月時点 1日負荷試験に使った場合の例 実質コスト差は約1/6になるケースも $1.284 /日 $0.2025 /日 大量の負荷かけ元サーバの管理 負荷試験環境の構築のポイント
  31. 65/85 負荷試験環境の構築のポイント (xhprof) 計測 起動 負荷実行 停止 破棄 負荷かけ元 インスタンス作成

    負荷シナリオ実行 負荷シナリオ停止 負荷かけ元 インスタンス破棄 負荷かけ元 本番同等の ゲームサーバ KVS DB Jenkins EC2 Spot Instance Fargate プロファイラ/ 監視ツール等 ELB エンジニア PC 大量の負荷かけ元サーバの管理
  32. 69/85 • ELB等クラウドのロードバランサは暖気しておく • 負荷をかける元サーバにNATを挟まない • 外部のAPIは必ずoffにできるようにしておく • PCから負荷をかけない •

    バッチのボリュームテストは必ず行う • 耐久試験(エージングテスト)も行う より効果的な負荷試験にするためには 負荷試験時の注意点
  33. 内製ツールでより問題を発見しやすく 80/85 SELECT * FROM table_name_00 WHERE id=N AND name=’S’

    x 3 SELECT * FROM table_name_00 WHERE id=102 AND name=’username2’ SELECT * FROM table_name_00 WHERE id=101 AND name=’username1’ SELECT * FROM table_name_00 WHERE id=100 AND name=’username0’ 全く同一あるいはループで発行されたクエリを集計 パラメータを 抽象化して集計 発行したクエリ Duplicate SQL Log Duplicate SQL Log