はじめに
こんにちは!TechBull 運営メンバーで駆け出しSREの相川(@riv_infra)です。今回はISUCON本でISUCONに入門してみたという記事を書いてみました!
ISUCONとは
ISUCONとは、Iikanjini Speed Up Contest(いい感じに スピードアップ コンテスト)の略称とのことです。
ISUCONとはLINEヤフー株式会社が運営窓口となって開催している、お題となるWebサービスを決められたレギュレーションの中で限界まで高速化を図るチューニングバトルです
ISUCON公式サイトより引用させて頂きましたが、「お題となるWebサービス」を実行している環境が参加チームごとに用意され、「決められたレギュレーション」の中でいかにサービスを高速化できるか競うコンテストのようです。私は昨年のISUCON14が行われた頃にISUCONの存在を初めて知ったので、今年は出場してみたいと思っています!
「お題となるWebサービス」とは
昨年のISUCON14では、「ISURIDE」というライドシェアサービスがお題となっていたようです。
今回の問題では、いわゆるタクシー配車・ライドシェアアプリをベースに、自動運転椅子のライドチェアサービス「ISURIDE」を題材としました。
日本国内でもタクシー配車アプリの利用が徐々に増え、ライドシェアに関する法整備も進んできている中、「単にレスポンスを速くする」だけでなく、マッチング機能を含むアプリケーション全体をより最適化するという課題に挑んでもらうために、このライドシェア(ライドチェア)サービスのテーマを選択しました。
引用: ISUCON14 問題の解説と講評
すごく凝られた出題動画があったので見てみましたが、最後の障害発生で心がキュッとなりました。障害が起こらないようチューニングしたい、、
「決められたレギュレーション」とは
昨年のISUCON14では、下記のような記載がありました。
高速化の際、主催者より問題として与えられたWebシステムから、以下の部分は変更しないこと。
アクセス先のURI ただしサーバー側で生成する部分(IDなど)は文字種([0-9や[0-9a-zA-Z_ など)を変えない範囲で自由に生成しても良い
・レスポンス(HTMLのDOM、JSONオブジェクト等)の構造 表示に影響しない範囲での空白文字の増減は許可される
・JavaScript/CSSファイルの内容
・画像および動画等のメディアファイルの内容各サーバにおけるソフトウェアの入れ替え、設定の変更、アプリケーションコードの変更および入れ替えなどは一切禁止しない。 ベンチマーク中に、ポータル・マニュアル・レギュレーションなどで利用が認められたサーバー以外の外部リソースを使用する行為(他のインスタンスに処理を委譲するなど)は禁止する。 ただしモニタリングやテスト、開発などにおいては、PCや外部のサーバーを利用しても構わない。
引用: ISUCON14 レギュレーション
詳細は、引用元をご確認頂きたいですが、Webサービスのユーザー側からの見た目は変えずに、それを実現している方法を色々変えてチューニングするという形でしょうか。
ISUCON本とは
ISUCONの強豪の方や作問者の方々が著者となっている本です。
本書では,お題となるWebサービスをひとつ用意して,手を動かしながら高速化手法を学んでいきます。Webサービスがどのくらいの負荷に耐えられるか,どのくらいの負荷で不具合が起こるかを検証し,不具合が起こる原因を突き止め,改善していきます。また,負荷に対応する方法だけでなく,負荷を発生させる方法(ベンチマーカーの作成方法)も紹介します。
本書を読んで,Webサービス高速化について理解を深め,性能を向上させましょう。
引用: 技術評論社 書籍ページ
Webサービスの開発や運用をしているが、動作が重くて困っている方やISUCONに出場してみたい(より良い成績を収めたい)方にお勧めとのことです。本書では、題材となるWebサービス(private-isu)を通してパフォーマンスチューニングや負荷試験の方法を学んでいくとのことです。
ちなみに、TechBullコミュニティマネージャーの@adachin0817さん(@adachin0817)がTECH WORLDさんの動画に出て本書をおすすめされていました。私も以前、adachinさんにお勧めされて購入していました。
Webサービス private-isuとは
private-isuとは、金子達哉さん(catatsuyさん)が中心となって2016年にピクシブ株式会社で開催された社内ISUCONのために作成し、一般公開されているものです。private-isuで提供されるWebサービスは、Isucogramという名前の画像投稿サイトです。ユーザー登録機能とログイン機能があり、ログインしたユーザーが画像を投稿したり、投稿された画像に対してコメントを書き込めたりする機能があります。
ISUCON本 3-1 本書で扱うWebサービス private-isu より一部引用
環境構築
ここからは、私が実際に試してみたことを書いていきます。
まず環境構築ですが、私はM1 Macを使っているので気楽に構築できるcloud-initを使った方法で構築してみました。この方法は、matsuuuさんがcloud-init-isuconというリポジトリでISUCON過去問環境をcloud-initを使って気軽に構築できるように公開してくださっています。
Multipassでの利用方法に沿って、下記コマンドを実行して競技者用インスタンスとベンチマーカー用インスタンスを起動しました。
1 2 |
$ multipass launch --name isu-app --cpus 2 --disk 16G --memory 4G --cloud-init app.cfg 24.04 $ multipass launch --name isu-benchmarker --cpus 4 --disk 16G --memory 4G --cloud-init benchmarker.cfg 24.04 |
multipass shell インスタンス名
でインスタンスにログインし、tail -f /var/log/cloud-init-output.log
で、cloud-initによる構築の進捗状況が確認できました。
Cloud-init finished
というログが吐かれたので、無事cloud-initによる構築完了が確認できました。cloud-initのcfgファイルを確認すると、Ansibleが使われているのが分かります。
1 |
$ ansible-playbook -i hosts image/ansible/playbooks.yml --skip-tags nodejs |
Cloud-init finished
のログの上部でAnsibleの実行結果が表示されており、failed=0で問題なくAnsibleも実行できていることが確認できました。
初回ベンチマーカーの実行 初回:1121点
ベンチマーカーインスタンス上で、下記のコマンドを実行します。
1 2 |
$ cd /home/isucon/private_isu.git/benchmarker $ ./bin/benchmarker -u ./userdata -t http://{競技者用インスタンスのIPアドレス}/ |
初回スコアは、1121点でした。
書籍より一部引用させて頂きますが、ベンチマークスコアはベンチマーカーが発行したHTTPリクエストを元にPOSTリクエストや画像のPOSTリクエスト、ステータスコード5xxやタイムアウトしたリクエストなどで係数を加味して算出されているとのことです。
チューニングを行い、一定時間の間にベンチマーカーがより多くのHTTPリクエストを発行する(競技者用インスタンスがより多くの処理を行う)ことができれば得点アップに繋がります。なお、ハードウェアの性能にも依存するため環境が異なる場合にスコアを単純に比較することはできません。
スロークエリログの設定
初回ベンチマーク実行時に、競技者用インスタンスでtopコマンドを実行していました。以下画像はある一時点の結果になります。
画像から、下記2点に気づくことができます。
- MySQL(mysqld)のプロセスのCPU使用率が100%に近い
- CPU2コアのうち1コアがほぼidle状態
まず、分析のためスロークエリログを有効にします。
スロークエリーログは、実行に
long_query_time
秒を超える時間がかかり、少なくともmin_examined_row_limit
行を検査する必要がある SQL ステートメントで構成されます。実行時にスロークエリーログを無効化または有効化したり、ログファイル名を変更したりするには、グローバルな
slow_query_log
およびslow_query_log_file
システム変数を使用します。slow_query_log
を 0 に設定してログを無効にするか、1 に設定してログを有効にします。 ログファイルの名前を指定するには、slow_query_log_file
を指定します。 ログファイルがすでに開いている場合、ログファイルが閉じて新しいファイルが開きます。
引用: MySQL 8.0 5.4.5 スロークエリーログ
MySQLの設定ファイル(デフォルト: /etc/mysql/my.cnf)内で、下記を設定します。
1 2 3 4 |
[mysqld] slow_query_log = 1 slow_query_log_file = <スロークエリログの出力先ファイルパス> long_query_time = <これよりも時間がかかった場合にスロークエリとして判定する閾値(秒)> |
long_query_time
に指定する秒数について、実運用時は0より大きい値を指定し長時間かかったクエリを抽出するのが一般的ですが、一回の実行が高速でも大量に発行されているクエリが問題になることがあるため、パフォーマンスチューニングにおいては0に設定することが推奨とのことです。
MySQLの設定ファイルを変更した後、MySQLのサービスを再起動します。
1 |
$ sudo systemctl restart mysql |
DB インデックス追加 1121点 → 11548点
スロークエリログの設定を有効にしてベンチマークを再度実行し、ログの中身を見てみると下記のようになっていました。
commentsテーブルへのpost_idによる検索を行うクエリが大量に発行されていました。このクエリの処理にかかる時間を減らすことが出来ればボトルネックを解消できそうです。
そこで、EXPLAINを用いてこの同じ種類のクエリの実行計画を見てみました。
1 |
EXPLAIN SELECT * FROM `comments` WHERE `post_id` = 9988 ORDER BY `created_at` DESC LIMIT 3; |
EXPLAIN
は、クエリー実行計画 (つまり、MySQL がクエリーをどのように実行するかの説明) を取得するために使用されます。EXPLAIN を使用すると、インデックスを使用して行を検索することでステートメントがより高速に実行されるように、テーブルにインデックスを追加する場所を確認できます。
引用: MySQL 8.0 13.8.2 EXPLAIN ステートメント
確認したところ、typeがALLとなっておりフルテーブルスキャンが行われていました。
EXPLAIN
出力のtype
カラムには、テーブルの結合方法が示されます。 JSON 形式の出力では、これらはaccess_type
プロパティの値として検出されます。 次のリストに、もっとも適切な型からもっとも不適切な型の順番で並べた結合型を示します。ALL
フルテーブルスキャンは、前のテーブルの行の組み合わせごとに実行されます。 これは、通常テーブルが const とマークされていない最初のテーブルである場合には適しておらず、通常ほかのすべてのケースで著しく不適切です。 通常、定数値または以前のテーブルからのカラム値に基づいて、テーブルからの行の取得を可能にするインデックスを追加することで、ALL を回避できます。
引用: MySQL 8.0 8.8.2 EXPLAIN 出力フォーマット
引用元にインデックスを追加することでALLを回避できるとあります。インデックスについてあまり理解できていませんが、書籍に沿ってインデックスを追加してみます。
1 |
ALTER TABLE comments ADD INDEX post_id_idx (post_id, created_at DESC); |
インデックス追加後、再度実行計画を確認してみると、typeがrefとなっていました。
ref
前のテーブルの行の組み合わせごとに、一致するインデックス値を持つすべての行がこのテーブルから読み取られます。
ref
は、結合でキーの左端のプリフィクスのみが使用される場合、またはキーがPRIMARY KEY
やUNIQUE
インデックスではない場合 (つまり、結合で、キー値に基づいて単一の行を選択できない場合) に使用されます。 使用されているキーがほんの数行にしか一致しない場合、これは適切な結合型です。
引用: MySQL 8.0 8.8.2 EXPLAIN 出力フォーマット
この変更後、ベンチマークを行うとスコアは11548点に上昇しました。(肝心のスコアはスクショ忘れ)
topをすると、MySQL(mysqld)のプロセスのCPU使用率がかなり下がっていました。また、この段階ではまだ1コアしか使用できていないため、%Cpu(s): 46.8 idとなっています。
unicorn workerプロセスを1から4に変更 11548点 → 24883点
unicorn_config.rbでworker_processes 1
と書かれた部分をworker_processes 4
に変更します。
下記のコマンドでアプリケーションサーバーを再起動します。
1 |
$ sudo systemctl restart isu-ruby |
この変更後、ベンチマークを行うとスコアは24883点に上昇しました。(肝心のスコアはスクショ忘れ)ベンチマーク実行中にhtopした結果、unicornのworkerプロセスが4つ確認できました。それぞれCPU使用率が25%程度になっています。
dstat --cpu
したところ、CPUが1コアだけではなく2コアとも使い切れているのが確認できました。
この後の流れ
書籍の中で、この後はアクセスログの解析ツールであるalpをインストールして解析したり、静的ファイルをnginxで配信するなどを行います。その後、いよいよアプリケーションのコードに手を加えていきます。
書籍の中では初期状態が650点のところから、最終的には約32万点まで向上する流れを丁寧に解説されています。個人的には攻略本を見ながらゲームをする感じでこんなに楽しいんだ!と思いました。何か改善を加えてスコアが伸びてパフォーマンスが向上したことを実感できるのは嬉しくて楽しいなと思いました。結構ハマる人は多いのではないでしょうか?
記事を読んでいただいて、興味があるけどまだ触ったことがないよという方、ぜひ一緒にISUCON本でISUCONに入門してみましょう!
おわりに
今回はISUCONの紹介と、ISUCON本を通してパフォーマンスチューニングを体験してみたという記事を書いてみました。今年もISUCONが開催されるのかは不明なのですが、開催される場合にはTechBullの人と一緒に出るのも面白そうだなぁとも思っています。作問や環境の提供など、運営の方々にリスペクトです。すごく有難い、素晴らしいなと思います。ぜひ続いていってほしいなと思いました。
告知
TechBull主催のLT会が開催されます!詳しくはconnpassをチェックお願いします!!
https://techbull.connpass.com/event/351941/
こんにちは😃
GW前半、皆さんいかがお過ごしでしょうか?さて、TechBull主催のLT会が公開されました🎉
TechBullメンバーによるLTと一部公募枠もありますので是非ご応募下さい!日時:6/4(水) 19:20-22:00
場所:Datadog Japanイベントスペース#TechBull #TechBull_LT https://t.co/W1KV7wm6Tg— TechBull☁️Engineer Community (@techbull_cloud) April 30, 2025
また、私の所属企業にて休日に会議室を借りてもくもく会が出来るようになりました!
ある程度定期的にやっていく予定ですので、ぜひご参加ください!!次回は5/11です!
https://techbull.connpass.com/event/351525/
私の所属企業にて休日に会議室を借りてもくもく会が出来るようになりました🎉
今後はより快適に学習できるスペースを提供できて嬉しいです!
隔週もしくは少なくとも月イチで開催予定ですのでご興味あれば是非ご参加ください🥳#TechBull_もくもく会 https://t.co/k9IKjs3Qgp
— Masahiro Aikawa (@riv_infra) April 27, 2025

1997年生まれ。そろそろ3年目に入る駆け出しSRE。書籍やWebで学んだり様々な資格を取得するも、実務に役立つ実装力を身につけるという点で難しさを感じる。ひょんなことからTechBullに加入し課題をこなすことで、無事自社開発企業への転職に成功する。コミュニティ内ではもくもく会を主催したり、新規参画者の受け入れ1on1を実施している。