MySQL
isucon
perfomance

インターン生向けのISUCON CM

More than 1 year has passed since last update.

(esaのプレゼンモードで当日は発表しました)


突然ですが、質問です


  • MySQLなどにデータを保存するWebアプリケーションを作ったことはありますか?

  • Linuxサーバーにsshしたことはありますか?

  • AWSやGCPやさくらのVPSやさくらのクラウドなどなど、そういったサービスを使って自分専用のサーバーを作ったことはありますか?

あっても、なくても、皆さんにおすすめな情報があります!!


ISUCONとは


お題となるWebサービスを決められたレギュレーションの中で限界まで高速化を図るチューニングバトル、それがISUCONです



ISUCONについて


Webアプリケーションのチューニング


  • やったことがある人いますか?

  • どういったところがチューニングする必要があると思いますか?


実際のWebアプリケーション


  • 実際のWebアプリケーションでも、様々な事情でパフォーマンスに問題が出ます

  • アクセスが少ない時は問題が無くても、アクセスが増えた途端に問題が起こることもあります

  • そういったWebアプリケーションのチューニングを競技にして競い合うのがISUCONです


実際のISUCONの問題と流れについて


ポータルサイトでスコアを計測する


  • ポータルサイトがあり、ベンチマークを実行することができる


    • 自分のスコアを計測できる

    • 自分のサーバーに対してリクエストが来る

    • このスコアが一番高かったチームの勝利!



3cb985e1-8bf8-4972-8612-0ae0a98847c3.png


  • スコアの計測ができてから言語実装の切り替えなどを行う(重要)


    • 構成を変える毎にスコアを計測しないと、スコアを計測できなくなったときに何が原因か分からなくなる

    • 極力差し戻せるような作業を意識する

    • 社内ISUCONは初期実装がRubyだったのでRubyを選択した人は必要なかった

    • 切り替え方法はアナウンスがあるので従う



  • 実装を切り替えてスコア計測までできたら、構成を変える


ボトルネックの調べ方


  • 大きいところから絞っていく


    • チューニング全てにおいて言えること

    • どのページでどれだけ時間を使っているのか?から調べるのがよい

    • どう調べるか?



  • フロントサーバーにnginxを使用しているので、nginxのアクセスログからベンチマーカーのアクセス傾向を調べる


    • 各ページの実行回数と実行時間が取りたい




nginxとアプリケーション


  • nginxはアプリケーションの前段に置かれている


    • ユーザー => nginx => APP



  • アプリケーションにもよるが、PHPやRuby(unicorn)などの場合はアプリケーションサーバーはマルチプロセスモデルで動く


    • 1reqを1プロセスが担当するというアーキテクチャ

    • 1プロセスのメモリ消費量がそれなりに大きいので、1台のサーバー上に大量のプロセスを起動できない

    • CSS・JSなど静的ファイルの配信などでも1プロセス占有される

    • アプリケーションは動的に生成する必要があるコンテンツを返すために用意されたもので、静的ファイルで使う必要は無い

    • クライアントが遅い回線を使用していた場合、クライアントにリクエストを送りきるまで1プロセスが占有される



  • nginxはイベント駆動のアーキテクチャ


    • 1プロセスが複数リクエストを受けられる

    • ロジックは書けない(luaやmrubyを除く)が、高速にレスポンスを返せる

    • 静的ファイル配信のようなアプリケーションを通す必要がないものはnginxから直接返してしまえば良い

    • 遅いクライアントに対してレスポンスを返す時はnginxがバッファリングしてくれるので、アプリケーションはnginxに対してレスポンスを返すことだけに注力すれば良い



  • nginxでログを取る


    • アプリケーションからレスポンスが返ってくるまでに何秒かかったのかログを取ることができるので、それを使うことでアプリケーションのボトルネックやリクエスト数が多いページなどを調べることが容易にできる

    • ログファイルはLTSVにすると集計スクリプトを書きやすい

    • Labeled Tab-separated Values (LTSV)

    • nginxだとlog_formatで、$path$upstream_response_timeを出力すればよい

    • 集計スクリプトは事前に作るか、ツールがいくつか公開されているので使い方を調べて使う

    • IDなどURLは変わっても同一と見なしたいものがあるので、正規表現などを使ってまとめられるようにする



参考:


アクセスログの解析結果

sort by total_time

avg total count method path
0.31 256.54 820 GET /image/:id.jpg
0.42 78.17 188 GET /
0.32 48.55 152 GET /image/:id.png
0.56 39.45 71 GET /posts/:id
0.27 36.40 134 POST /login
0.54 27.13 50 GET /@:user
0.37 23.32 63 GET /js/jquery.timeago.js
0.35 21.83 63 GET /favicon.ico
0.32 20.40 63 GET /js/jquery.timeago.ja.js
0.32 20.24 63 GET /js/jquery-2.2.0.js
0.29 17.82 62 GET /css/style.css
0.27 16.92 62 GET /js/main.js
0.28 12.58 45 POST /
1.25 9.98 8 GET /posts?max_created_at=xxx
0.36 9.84 27 GET /image/:id.gif
0.14 5.13 36 POST /register
0.14 4.91 35 GET /admin/banned
0.37 3.74 10 GET /login
0.09 3.14 35 POST /comment
0.42 2.93 7 GET /logout
0.02 0.02 1 GET /initialize



  • GET /image/:id.(jpg|png|gif)をなんとかしないと行けない


  • GET /も重い

  • とりあえず静的ファイルはnginxから直接配信した方がよさそう


ベンチマーク実行中のプロセスの様子を確認する


  • topを見る

75eb7310-dd3c-4272-a951-cf65bc698653.png


  • CPUが200%とっている。 CPUがボトルネック

  • mysqlが200%maxのうちの150%を占めている


実行されているSQLを知る


  • 言語ごとのSQLのライブラリ


    • 各自調べてください



  • MySQLのgeneral_logやslow query logを使う方法


    • slow_query_logをONにしてlong_query_timeを0にすると、全てのSQLがスロークエリログへ出力されるので、動作させながら確認すれば、ページ内で実行されるSQLが簡単にわかる

    • long_query_timeを0.001とかに調整してtailしながらベンチマークをかけると、重いクエリだけを効率的に見ることができる

    • slow_query_logを集計してくれるツールとしては、percona-toolkitのpt-query-digestが有名




MySQLのインデックス

-- TABLE構造

CREATE TABLE comments (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`post_id` int NOT NULL,
`user_id` int NOT NULL,
`comment` text NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) DEFAULT CHARSET=utf8mb4;

-- 流されていたクエリ
SELECT * FROM `comments` WHERE `post_id` = 4391 ORDER BY `created_at` DESC LIMIT 3
SELECT COUNT(*) AS `count` FROM `comments` WHERE `post_id` = 10123
SELECT * FROM `comments` WHERE `post_id` = 8314 ORDER BY `created_at` DESC
SELECT COUNT(*) AS count FROM `comments` WHERE `post_id` IN (451,2755,3634,3657,3799,4564,6249,6852,7683,8521,8915,9247,9572,9875)


  • インデックスを使えるSQLを書けば高速にアクセスできる


    • ぜんぶpost_idのINDEXがない

    • INDEXを使うとB Treeを使って効率よく探索することができる



4d087213-1a59-4e95-aeb1-4f691da8ef5d.png

cf: https://ja.wikipedia.org/wiki/B%E6%9C%A8


ここから先は実際にやってみましょう


  • 今回紹介したのは最初のさわりです

  • まだまだ先はあるので是非解いてみて欲しい!!


今年のISUCONについて


  • ISUCON4はAWS、ISUCON5はGCPでしたが、今年のISUCON6はAzureです

  • Azure登録時にもらえるクーポンで基本やるので、お金はかからないはずです


    • (もしチーム全員がクレジットカードを持っていなければ運営に相談してください)



  • 最新情報はtwitterを見ていれば流れてくるはずです

  • 参加登録締め切りは 2016年9月9日(金) 12:00:00 JST です


    • 登録は早めにしてくれると喜びます



_人人人人人人人_

今すぐフォロー

@isucon_official

今すぐフォロー

 ̄Y^Y^Y^ Y^Y^Y^ ̄


ISUCONで学生枠1位を取るためには

(自分がやるならこうするという話です)


  • ISUCONの過去問をチーム全員で解いてみる


    • ここ数年のISUCONの過去問はAMIなどで公開されているのですぐに試すことができます

    • pixivの社内ISUCONもAMIが公開されています

    • VagrantやDockerでも試すことができるので個人でやるときはこちらでも良いかも(チーム練習は本番に近い環境がおすすめ)

    • matsuu/vagrant-isucon: ISUCON過去問を構築するためのVagrantfile集

    • matsuu/docker-isucon: Dockerfile for isucon

    • 本番の時間に極力合わせてやる(10時〜18時)と、細かいことも分かっておすすめです(どれくらいでお腹が空くかなど)



  • 解きながらか、解いた後に作戦会議をして役割を決めておく


    • 最初の30分から1時間くらいはやることが大体決まっているので、あらかじめ役割分担を決めておきましょう

    • ISUCONは時間との勝負なので最初の方は話し合っている時間もコスト

    • 開発手法(手元で構築するか、インスタンス上でやるかなど)も決めておく

    • 参考:自分たちのチームは手元で構築していました(過去に手元では容易に開発できない問題も出題されたことがあるので要注意)

    • 予選はリモートで行うので場所やご飯をどうするかなども決めておきましょう



  • 選んだ言語のプロファイリングの取り方を確認して、必ず使ってみる


    • 基本的にやったことがないことをISUCON当日にやるのは危険です

    • 他にも使う可能性がありそうなツールやライブラリは過去問などを使って、実際に使ってみましょう




ISUCONに


  • そろそろ出たくなってきましたか?

  • 質問したいことも出てきたと思います

  • なのでここから質問タイムにしたいと思います


    • その前に予想FAQを話します




予想FAQ


  • インフラの知識がありません


    • そもそもアプリケーション側を変更しなければ、基本的に上位に食い込めないのでインフラだけをやればよいという大会ではないです

    • 過去のISUCONの問題は全て公開されており、ここ数年のものならばAMIなども公開されていて簡単に試せるようになっているので、必ず練習しておきましょう

    • 新卒研修用のハンズオンの資料もあるので、それもおすすめ

    • ハンズオン講義

    • 過去のISUCONの問題を解いていれば、最初でつまずくことはないはず



  • 大学内に一緒にチームを組んでくれる人がいません


    • インターン生同士で組みましょう

    • Web系の会社のインターンに参加するメリットは、Webに興味のある同世代と出会えることです



  • 勝てる気がしません


    • 無料のお祭りなので勝ち負け気にせず参加しましょう

    • 実は学生枠から本戦に参加できるチーム数が去年の倍の10チームになりました

    • 一般枠の激戦ぶりに比べると、学生枠で本戦に行くことは桁違いに簡単なので、チームで一緒に過去問を解くなど練習をしておけば十分狙えます

    • 学生枠なら2位まで賞金があるので頑張ってください!



  • Webアプリケーションを作った経験がない OR 参考実装に得意な言語がありません(ISUCON6の予選で実装予定の言語実装:Ruby/PHP/Go/Perl/Python/Node.js)


    • いい機会なので勉強してみることをおすすめします

    • ISUCONではRuby on Railsのような重厚なフレームワークは使われず、例年の参考実装はRubyの場合はSinatraのような薄いフレームワークが使われています

    • 極力フレームワーク固有の知識などは必要が無いように、例年作られている(というかそうしないと他言語の実装を用意できない)ので挑戦しやすいです