Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
k6による負荷試験 入門から日常的な実践まで/Re:TechTalk #01
Search
FUJIWARA Shunichiro
March 26, 2025
Technology
670
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
k6による負荷試験 入門から日常的な実践まで/Re:TechTalk #01
https://hireroo.connpass.com/event/347502/
FUJIWARA Shunichiro
March 26, 2025
More Decks by FUJIWARA Shunichiro
See All by FUJIWARA Shunichiro
クラウドを使う側から、作る側へ / 大吉祥寺.pm 2026前夜祭
fujiwara3
8
2.1k
作るべきものと向き合う - ecspresso 8年間の開発史から学ぶ技術選定 / 技術選定con findy 2026
fujiwara3
9
5.7k
さくらのクラウドでのシークレット管理を考える/tamachi.sre#2
fujiwara3
2
390
Amazon ECS デプロイツール ecspresso の開発を支える「正しい抽象化」の探求 / YAPC::Fukuoka 2025
fujiwara3
13
13k
パフォーマンスチューニングのために普段からできること/Performance Tuning: Daily Practices
fujiwara3
9
6.8k
alecthomas/kong はいいぞ
fujiwara3
7
2.6k
ecspressoの設計思想に至る道 / sekkeinight2025
fujiwara3
12
3.8k
さくらのIaaS基盤のモニタリングとOpenTelemetry/OSC Hokkaido 2025
fujiwara3
4
5.3k
監視のこれまでとこれから/sakura monitoring seminar 2025
fujiwara3
12
5.9k
Other Decks in Technology
See All in Technology
現場の暗黙知を継承するAIエージェント — 対話から生まれる長期記憶と Skills
atsukish
0
190
Bill One 開発エンジニア 紹介資料
sansan33
PRO
7
20k
DMMブックスのNext.js化を加速させるAI活用 / Migrating DMM Books to Next.js with AI
kentarom
1
250
信頼性はSREだけのものじゃない
hkawaras
0
420
AI駆動開発はどこまで来たのか? ファインディの最新実態調査で読み解く現在地 Devin Con Tokyo
akiratom
4
2.2k
AI駆動開発を組織で促すために
lycorptech_jp
PRO
7
9k
AI時代の「OAuth認証」にどう物申すか?(OAuth/OIDC Numa (Immersion) Workshop 2026)
oidfj
PRO
0
400
MCPを待つな、パスキーを拡げよう(OAuth/OIDC Numa (Immersion) Workshop 2026)
oidfj
PRO
0
400
Dylib Hijacking on macOS: Dead or Alive?
patrickwardle
0
170
Master Dataグループ紹介資料
sansan33
PRO
1
4.9k
【Oracle AI Spotlight ウェビナー】AWSか、Azureか、Google Cloudか。その議論にオラクルを含める意義。
oracle4engineer
PRO
1
110
GopherCon @シアトル に行ってきました
logica0419
0
460
Featured
See All Featured
Everyday Curiosity
cassininazir
0
300
GitHub's CSS Performance
jonrohan
1033
470k
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
260
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1k
The Curse of the Amulet
leimatthew05
2
14k
Raft: Consensus for Rubyists
vanstee
141
7.7k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
510
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
230
Documentation Writing (for coders)
carmenintech
77
5.5k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.1k
Become a Pro
speakerdeck
PRO
31
6.2k
Transcript
k6による負荷試験 入門から日常的な実践まで 2025.03.26 Re:TechTalk#01 @fujiwara 藤原俊一郎
@fujiwara さくらインターネット株式会社 クラウド事業本部 ISUCON 1,2,5,11 優勝4回 ISUCON 3,8,12,13 運営(出題)4回 github.com/kayac/ecspresso
Amazon ECS デプロイツール github.com/fujiwara/lambroll AWS Lambda デプロイツール
おことわり このトークは2023年6月の 「TechFeed Exports Night#20」 で発表したものを元に加筆修正したものです
今回話す「負荷試験」の範囲 測定対象のWebサービス(アプリケーション)に対して 機械的にリクエスト(HTTPなど)を送信して 「性能(パフォーマンス)」を計測する ところで 「性能」 とは…?
負荷試験をする「前」に考えること ゴールを決める レイテンシ(レスポンスタイム)が目標? どのレスポンスを何秒で返せればOKなのか 平均値? 中央値? P99? max? そのレイテンシが保てる最大の並列アクセス数は? スループット(単位時間内に処理できるリクエスト数)が目標?
レイテンシ要件はない? レイテンシ1secで1,000並列 レイテンシ10secで10,000並列(どちらも1,000req/sec) あるサーバーリソースでのxxの最大化が目標?
負荷試験をする「前」に考えること その試験で測りたいものを言語化する レイテンシ スループット サーバーリソースの利用率・利用量(コストも含む) 運用中に実際に起きるどのような状況で、これらの数値目標を達成するのか 【具体的な例】 状況 : Push通知から◦◦分以内に◦◦人のユーザーがアプリを起動する
シナリオ : アプリが起動してホーム画面に遷移するときに発生するAPIアクセス 目標 : 平均レイテンシ250msec、P99 2sec、サーバーエラーなし 詳しくは ISUCON本 1章へ
負荷試験をする「前」にやること 負荷をかける対象のサーバーリソースはできるだけ固定する →「AutoScaling」的なものを止めておく 負荷試験には 「変数が多い」 変数の例: シナリオ(測定対象URL)、リクエストの送信レート、並列度… 固定できないもの(最近多い)は、そのサイズ(キャパシティ)を同時に記録しておく
負荷試験をする「前」にやること サーバー側のメトリクスを本番同様に取得して、ダッシュボードを作る 最低でも以下を一目で見られる状態に 各種CPU使用率 HTTP スループット(req/sec)、レイテンシ、statusコード別 データベースへのクエリ数(など) アプリケーションサーバー固有の情報 同時リクエスト処理数(worker数) job
queueがあるならそのメトリクス ネットワークトラフィック
ツールの選び方 最初におすすめ - k6 https://k6.io JavaScriptでシナリオが書ける (Node.JSではない) 実行エンジンは Go (軽量、省メモリ)
他のツール/自作を検討したほうがいい場合も リクエストやレスポンスbodyが特殊 (k6でもgRPC, GraphQLはサポート) gRPC https://k6.io/docs/using-k6/protocols/grpc/ GraphQL https://k6.io/blog/load-testing-graphql-with-k6/ JavaScriptよりも他の言語が得意な人が多い場合 複数シナリオ間で連係や同期を取る必要がある場合
ゲームのレイドバトルとか 自作用Go言語フレームワーク isucandar https://github.com/isucon/isucandar ISUCON本 付録Bに解説あり
シナリオの作り方 まず単一URL連打から import http from 'k6/http' import { check }
from 'k6' export default function () { let res = http.get('https://example.com/') check(res, { 'success': (r) => r.status === 200 }) } いきなり複雑なものは書かない
k6で実行 最初は「並列度(vus=virtual users)」= 1 から $ k6 run --vus 1
--duration 300s simple.js checks.............: 99.98% ✓ 52644 ✗ 6 http_req_duration..: avg=285.56ms min=32.93ms med=144.61ms max=30.05s p(90)=521.34ms p(95)=788.36ms http_reqs.. ......: 52650 172.404676/s (いっぱい出力があるけど)とりあえずこの3個を見る checks: コード内の check() の成功・失敗数 レイテンシ: http_req_duration スループット: http_reqs
結果を評価する 1. k6の出力とサーバー側のメトリクスに齟齬がないか →メトリクスの取得がおかしい可能性が高いので見直す 2. checksは想定通りか →エラーが目標/想定より多い場合は性能を評価する意味がない 原因を調査する 3. レイテンシは目標に達しているか
→これ以上並列度を増やすのはたいてい無意味 ボトルネックの調査をする 4. スループットは目標に達しているか or →並列度を2倍にして変化を見る 無闇に変数を変えて試さない
結果を評価しながら並列度/サーバーリソースを増やしていく 並列度=1で エラー率/レイテンシが目標に達している スループットが目標に達していない →並列度を増やすことでスループットが増加する「可能性がある」 並列度を増やしていくとある時点で… スループットが上がらない エラー率/レイテンシが目標に達しなくなる →「サーバーリソースを増強する」ことでレイテンシが改善/スループットが増加する 「可能性がある」
無闇にサーバーリソースを変えて試さない(時間の無駄)
シナリオを増やしていく 1. 参照系のリクエスト/画面遷移を足す 2. ログイン/更新系のリクエストを足す (コードの具体例はISUCON本 4章に) 本番のアクセスパターンと負荷を網羅しようと思うのはやめよう(大変) 1. 一連のシナリオごとに実行する
例: トップ→ログイン→マイページ→お知らせを見る これだけでも特定の箇所で大きな問題がある場合には改善点が分かる 2. 複数のシナリオを混ぜて実行する 複数シナリオを実際に想定される程度の割合で混ぜる
負荷試験中に気を付けること 負荷は5分以上掛ける メトリクスの解像度が1分の場合、実行開始と終了時を除いた3分間のメトリ クスしか信用できない エラー率/レイテンシが目標に達しない場合、並列度を増やさない たいてい状況は悪化するので時間の無駄 常に「目標」を意識して負荷を与える、結果を評価する ベンチマーカーがボトルネックになっていないか気を付ける シナリオが重い、ツールが速くない場合、クライアントが先に根を上げる
クライアント側で起きる問題の頻出例 (ISUCON本 9章を参照) ネットワーク帯域が上限を打っている 1Gbpsの回線で1MBのレスポンスを取得→(たったの)125req/sec(=125MB/sec) HTTP Keep-Aliveが無効になっている TCP 3 way
handshake / TLS handshake のオーバーヘッドが大きい 無駄にファイルディスクリプタ(ソケット)を使う Goで自作した場合にやりがち: http.Response.Body を全て読み切らない →次のリクエスト時は新規のTCP接続になる ファイルディスクリプタを使い果たしている ulimit -n (max open files)がデフォルトの1024 ローカルポート(エフェメラルポート)が枯渇している 大量/高速にリクエストを送受信すると使い果たす
日常的に負荷試験をする 負荷試験=取りかかるのが大変(というイメージ) 小さいシナリオから始める 日常的に実行する 定期的に実行する 負荷試験を「日常の一部」にする→「いざという時にもすぐ取りかかれる」
日常に組み込む具体例 あるプロダクトで… 「ElastiCache Redisのバージョンアップ(フェイルオーバー)をしたい、 (ドキュメントによれば) ほぼ無停止でできるはずだが、 怖いのでメンテナンスを入れたい」 こういうときにも負荷試験ツールは役に立つ 「負荷試験」=「実際のリクエストをある程度再現して送信し続ける」 負荷試験を実行しながらフェイルオーバーを実行
→ 何が起きるかを検証すればよい
用意したシナリオ 1. トップページにアクセス 2. トップページから呼ばれるAPI(認証なし)を複数並列で叩く 3. ログインフォームにアクセス 4. ユーザー名とパスワードをPOSTしてログインする 5.
ログインセッションが必要なAPI(要認証)を叩く コンポーネント(CDN, LB, WebApp, MySQL, Redis)を一通り通過する ストレージからの読み込み、書き込み処理が両方ある これを回しながら作業すると、各コンポーネントのエラーの発生と回復が検知できる
「不安だからメンテ入れましょう」からの脱却 どれぐらいエラーが起きるか分からない どれぐらい復旧に時間が掛かるか分からない 「怖いので」サービス停止メンテナンスを入れてやりたい 知らない = 怖い だけなので、試せばよい 検証環境で負荷を掛けた状態でバージョンアップ(Failover)する 実際にどれぐらいのエラーが発生して、回復するか観察する
普段発生しているエラー数、頻度と比較してメンテナンスの必要性を考える (設定ミスなどで)回復がうまくできない状態も検知できる
本番でも負荷試験リクエストを流しながらメンテナンス 本番でも「軽い」負荷をかけながらメンテナンスするといいこともある フェイルオーバーなどでアプリケーション-ミドルウェア間の通信が切断 → アプリケーションでエラーが発生する 次のリクエストで再接続されて解消する アクセスがそれほど多くないサービスの場合、 「エラーを踏む」役目を 負荷試験のリクエストが肩代わりしてくれる k6
executor という概念があり、送信するリクエストのレートや並列度を制御できる https://grafana.com/docs/k6/latest/using-k6/scenarios/executors/
GitHub Actions等でも日常的に実行 k6 は CLI ツールなので GitHub Actions などでも簡単に実行できる リポジトリにシナリオを置いておく
本番/ステージング/開発環境等に向けられるようにしておくと便利 on: workflow_dispatch: inputs: target: description: "target to load test" required: true type: string jobs: load_test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: grafana/setup-k6-action@v1 - uses: grafana/run-k6-action@v1 with: path: | ./load_tests/${{ inputs.target }}.js
まとめ 負荷試験はやる「前」の準備が大事 ゴールと目標の設定 いたずらに変数を増やさないために準備 負荷試験をやっているときは「評価」が大事 結果を評価してから次の試行を いたずらに試行錯誤で時間を無駄にしない 負荷を与える側にもハマりどころはいろいろある クライアント側のボトルネックに気がつかないと時間を無駄に 日常的に負荷試験していくとよい
小さいシナリオから育てていく 本番でも負荷試験リクエストを流しながらメンテナンスする