isucon5 予選をphpで戦った話

62
ISUCON5 予選を PHPで戦った話 2015/10/28 #phpstudy 株式会社サイバーエージェント

Upload: suguru-shirai

Post on 12-Apr-2017

778 views

Category:

Software


0 download

TRANSCRIPT

Page 1: ISUCON5 予選をPHPで戦った話

ISUCON5 予選をPHPで戦った話

2015/10/28#phpstudy株式会社サイバーエージェント⽩白井  英

Page 2: ISUCON5 予選をPHPで戦った話

2

お前、誰よ• 株式会社 サイバーエージェント• SGE統括本部技術統括室 CTO• 白井 英• エンジニア• Twitter@goodoo• Bloghttp://ameblo.jp/goodoo• DQ10すぐちむ (FB392-435) プクリポ(旅芸人)

Page 3: ISUCON5 予選をPHPで戦った話

• ISUCONとは?• 準備• 何をしたか• 何が足らなかったか• まとめ

Agenda

Page 4: ISUCON5 予選をPHPで戦った話

ISUCONとは

Page 5: ISUCON5 予選をPHPで戦った話

・Webアプリケーションの 高速化コンテスト・1日かけてWebアプリケーションを チューニング・レギュレーション内であれば何でも可

Page 6: ISUCON5 予選をPHPで戦った話

・複数言語用意されていた(今回は、Ruby,Perl,Python,PHP)・ベンチマークツールのスコアで競う・1チーム3名以内(2名はいないとつらい・・・)

Page 7: ISUCON5 予選をPHPで戦った話

準備

Page 8: ISUCON5 予選をPHPで戦った話

前日までにしたこと・・

Page 10: ISUCON5 予選をPHPで戦った話

スライドを熟読

Page 11: ISUCON5 予選をPHPで戦った話

チームで分担して準備する事を4つ決めた

Page 12: ISUCON5 予選をPHPで戦った話

1. コミュニケーションツール

Page 13: ISUCON5 予選をPHPで戦った話

2. レポジトリ

Page 14: ISUCON5 予選をPHPで戦った話

3. Wiki

Page 15: ISUCON5 予選をPHPで戦った話

4. GCPのプロジェクトの設定

Page 16: ISUCON5 予選をPHPで戦った話

そして当日・・

Page 17: ISUCON5 予選をPHPで戦った話

何をしたか

Page 18: ISUCON5 予選をPHPで戦った話

ルールの確認

Page 19: ISUCON5 予選をPHPで戦った話

予選通過予選は以下のルールで通過者が決定します。

1日目、2日目、それぞれで3000点に最も早く到達したチーム (ただし予選終了後の追試の対象には含まれます)それぞれの日で最後に提出した有効なスコアの上位4チーム上記10チームを除き、1日目と2日目を通した上位10チームまたこれとは別枠で、1日目と2日目を通した学生枠の上位5チーム

Page 20: ISUCON5 予選をPHPで戦った話

開始して最初の1時間

Page 21: ISUCON5 予選をPHPで戦った話

初期状態でベンチマークツールを走らせる・・・SCORE 100ぐらい(Ruby)

Page 22: ISUCON5 予選をPHPで戦った話

次にRuby -> PHPDBのバックアップ(dump)を実行

Page 23: ISUCON5 予選をPHPで戦った話

SCORE 800ぐらい

Page 24: ISUCON5 予選をPHPで戦った話

チーム内での一言「PHP優秀じゃん」

Page 25: ISUCON5 予選をPHPで戦った話

ちなみに後から考えてわかったことですが最初にDBのdumpをとったためDBのデータがキャッシュにのった関係でスコアが8倍のびました決してRuby->PHPが効いた訳ではありません

Page 26: ISUCON5 予選をPHPで戦った話

DBまわりのチューニングをはじめる

Page 27: ISUCON5 予選をPHPで戦った話

pt-query-digestをいれてもらう(そのあとNewRelicもいれてもらった)

Page 28: ISUCON5 予選をPHPで戦った話

my.cnfどこ問題

Page 29: ISUCON5 予選をPHPで戦った話

/etc/my.cnfを変更しても反映されない・・・とりあえずmysql> set global XXX=xxxで逃げるでもslow-queryのファイルが吐き出せない・・・

Page 30: ISUCON5 予選をPHPで戦った話

/etcの下をさがす・・

Page 31: ISUCON5 予選をPHPで戦った話

あった!/etc/mysql/mysql.conf.d/mysqld.cnf

Page 32: ISUCON5 予選をPHPで戦った話

・クエリーキャッシュをON・とりあえずメモリまわりチューニング - innodb_buffer_pool - xxxx_buffer_size ・php-fpmのプロセス数を1->10へ

Page 33: ISUCON5 予選をPHPで戦った話

あれ・・・

Page 34: ISUCON5 予選をPHPで戦った話

3,000スコア越えてる!

Page 35: ISUCON5 予選をPHPで戦った話

しかし・・・

Page 36: ISUCON5 予選をPHPで戦った話

10分差で3,000スコア1番乗りならず

Page 37: ISUCON5 予選をPHPで戦った話

もっと早くやっておけば・・

Page 38: ISUCON5 予選をPHPで戦った話

気を取り直して

Page 39: ISUCON5 予選をPHPで戦った話

pt-query-digestの結果を愚直に直す

Page 40: ISUCON5 予選をPHPで戦った話

・INDEXをはる -> スロークエリチェック のループ (カラム数が4つのテーブルに  カラム数3つの複合インデックス  read命みたいなものも作る・・)

結果、0.1sec以上のスロークエリーは0

Page 41: ISUCON5 予選をPHPで戦った話

遅いページは・・・・

Page 42: ISUCON5 予選をPHPで戦った話

/ HTTP/1.1" 200 17331 "-" "Isucon5q bench" 1.614

Page 43: ISUCON5 予選をPHPで戦った話

/TOPページがおもい!

Page 44: ISUCON5 予選をPHPで戦った話

ここまでで開始して

3時間くらい

Page 45: ISUCON5 予選をPHPで戦った話

プログラムを修正する決意!

Page 46: ISUCON5 予選をPHPで戦った話

PHPはSlimという

マイクロフレームワークでかかれていた

Page 47: ISUCON5 予選をPHPで戦った話

直した場所!

Page 48: ISUCON5 予選をPHPで戦った話

$stmt = db_execute('SELECT * FROM entries ORDER BY created_at DESC LIMIT 1000'); while ($entry = $stmt->fetch()) { if (!is_friend($entry['user_id'])) continue; list($title) = preg_split('/\n/', $entry['body']); $entry['title'] = $title; $entries_of_friends[] = $entry; if (sizeof($entries_of_friends) >= 10) break; }

この処理でis_friendをよんでますが(loop中に)中身は $user_id = $_SESSION['user_id']; $query = 'SELECT COUNT(1) AS cnt FROM relations WHERE (one = ? AND another = ?) OR (one = ? AND another = ?)'; $cnt = db_execute($query, array($user_id, $another_id, $another_id, $user_id))->fetch()['cnt']; return $cnt > 0 ? true : false;

です。

Page 49: ISUCON5 予選をPHPで戦った話

loop中にSQLをなげるのをやめた

Page 50: ISUCON5 予選をPHPで戦った話

もう1カ所loop中に

クエリーを投げている場所があったが直せず※問題の詳細が知りたい方はこちら(http://isucon.net/)

Page 51: ISUCON5 予選をPHPで戦った話

一旦今のベストスコアを作ってみる

※他のメンバーも諸々チューニングしてくれましたが自分のわかる範囲のみ書いてます

Page 52: ISUCON5 予選をPHPで戦った話

各種ログを止める・slowlog・NewRelic・xdebug

Page 53: ISUCON5 予選をPHPで戦った話

結果

Page 54: ISUCON5 予選をPHPで戦った話

何が足らなかったか

Page 55: ISUCON5 予選をPHPで戦った話

いろいろ足らないのは承知の上ですが

1つだけやっておけばよかったこと

Page 56: ISUCON5 予選をPHPで戦った話

こたえは最初にやったこと

Page 57: ISUCON5 予選をPHPで戦った話

DBのdump=(データの

キャッシュのせ)

Page 58: ISUCON5 予選をPHPで戦った話

正しくは次のパラメータinnodb_buffer_pool_dump_at_shutdown=ONinnodb_buffer_pool_load_at_startup=ON

バッファプールのダンプ、リストアを実施を行う設定

Page 59: ISUCON5 予選をPHPで戦った話

まとめ

Page 60: ISUCON5 予選をPHPで戦った話

オンライン予選 利用言語比率Ruby   43.2% 67組Python  15.5% 24組Golang  14.2% 22組Perl    14.2% 22組PHP    12.9% 20組Java    2.6%  4組Common Lisp 0.6% 1組

Page 61: ISUCON5 予選をPHPで戦った話

本選出場が決まった27チームRuby   37.0% 10組Perl   25.9%  7組Golang  22.2%  6組Python  11.1%  3組PHP    3.7%  1組未回答   7.4%  2組

Page 62: ISUCON5 予選をPHPで戦った話

頑張れPHP