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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
FUJIWARA Shunichiro
March 26, 2025
Technology
610
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
作るべきものと向き合う - ecspresso 8年間の開発史から学ぶ技術選定 / 技術選定con findy 2026
fujiwara3
9
4.8k
さくらのクラウドでのシークレット管理を考える/tamachi.sre#2
fujiwara3
2
340
Amazon ECS デプロイツール ecspresso の開発を支える「正しい抽象化」の探求 / YAPC::Fukuoka 2025
fujiwara3
13
12k
パフォーマンスチューニングのために普段からできること/Performance Tuning: Daily Practices
fujiwara3
9
6.7k
alecthomas/kong はいいぞ
fujiwara3
7
2.5k
ecspressoの設計思想に至る道 / sekkeinight2025
fujiwara3
12
3.7k
さくらのIaaS基盤のモニタリングとOpenTelemetry/OSC Hokkaido 2025
fujiwara3
3
4.3k
監視のこれまでとこれから/sakura monitoring seminar 2025
fujiwara3
12
5.9k
困難を「一般解」で解く
fujiwara3
10
4.4k
Other Decks in Technology
See All in Technology
Oracle AI Database@Azure:サービス概要のご紹介
oracle4engineer
PRO
6
2k
Oracle AI Database@AWS:サービス概要のご紹介
oracle4engineer
PRO
4
3k
スタートアップにAmazon EKSは早すぎる? マルチプロダクト戦略を加速する Platform Engineeringの実践 / Is Amazon EKS Too Soon for Startups? Practical Platform Engineering to Accelerate a Multi-Product Strategy
elmodev09
0
370
Android の公式 Skill / Android skills
yanzm
0
160
気軽に使える"情報のハブ"としてのNotion活用 〜フロー情報の集積点 と、 Claude Code × Notion AI〜
syucream
1
150
SteampipeとExcel Power QueryでAWS構成定義書の作成を自動化する
jhashimoto
0
160
Agile and AI Redmine Japan 2026
hiranabe
3
290
現地で盛り上がった WWDC26 Keynote
zozotech
PRO
1
270
あなたの知らないPDFのアクセシビリティ
lycorptech_jp
PRO
0
220
AWS Security Hub CSPMの成功・失敗体験
cmusudakeisuke
0
260
【Cyber-sec+】経営層を"動かす"ための考え方
hssh2_bin
0
200
[AWS Summit Japan 2026]迷っているあなたへ_小さな一歩が、やがて自分を助けてくれる
sh_fk2
1
160
Featured
See All Featured
Facilitating Awesome Meetings
lara
57
7k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
140
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.6k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.4k
Google's AI Overviews - The New Search
badams
0
1k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
360
Context Engineering - Making Every Token Count
addyosmani
9
970
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
410
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
Designing Powerful Visuals for Engaging Learning
tmiket
1
420
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
370
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
まとめ 負荷試験はやる「前」の準備が大事 ゴールと目標の設定 いたずらに変数を増やさないために準備 負荷試験をやっているときは「評価」が大事 結果を評価してから次の試行を いたずらに試行錯誤で時間を無駄にしない 負荷を与える側にもハマりどころはいろいろある クライアント側のボトルネックに気がつかないと時間を無駄に 日常的に負荷試験していくとよい
小さいシナリオから育てていく 本番でも負荷試験リクエストを流しながらメンテナンスする