Successfully reported this slideshow.
Your SlideShare is downloading. ×

ISUCON5 予選をPHPで戦った話

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad

Check these out next

1 of 62 Ad
Advertisement

More Related Content

Slideshows for you (20)

Similar to ISUCON5 予選をPHPで戦った話 (20)

Advertisement

Recently uploaded (20)

ISUCON5 予選をPHPで戦った話

  1. 1. ISUCON5 予選を PHPで戦った話 2015/10/28 #phpstudy 株式会社サイバーエージェント ⽩白井  英
  2. 2. 2 お前、誰よ • 株式会社 サイバーエージェント • SGE統括本部技術統括室 CTO • 白井 英 • エンジニア • Twitter @goodoo • Blog http://ameblo.jp/goodoo • DQ10 すぐちむ (FB392-435) プクリポ(旅芸人)
  3. 3. • ISUCONとは? • 準備 • 何をしたか • 何が足らなかったか • まとめ Agenda
  4. 4. ISUCONとは
  5. 5. ・Webアプリケーションの  高速化コンテスト ・1日かけてWebアプリケーションを  チューニング ・レギュレーション内であれば何でも可
  6. 6. ・複数言語用意されていた (今回は、Ruby,Perl,Python,PHP) ・ベンチマークツールのスコアで競う ・1チーム3名以内 (2名はいないとつらい・・・)
  7. 7. 準備
  8. 8. 前日までにしたこと・・
  9. 9. http://www.slideshare.net/kazeburo/isucon-yapcasia-tokyo-2015
  10. 10. スライドを 熟読
  11. 11. チームで分担して 準備する事を4つ決めた
  12. 12. 1. コミュニケーションツール
  13. 13. 2. レポジトリ
  14. 14. 3. Wiki
  15. 15. 4. GCPのプロジェクトの設定
  16. 16. そして当日・・
  17. 17. 何をしたか
  18. 18. ルールの確認
  19. 19. 予選通過 予選は以下のルールで通過者が決定します。 1日目、2日目、それぞれで3000点に最も早く到達したチーム (ただし予選終了後の追試の対象には含まれます) それぞれの日で最後に提出した有効なスコアの上位4チーム 上記10チームを除き、1日目と2日目を通した上位10チーム またこれとは別枠で、1日目と2日目を通した学生枠の上位5チーム
  20. 20. 開始して 最初の1時間
  21. 21. 初期状態でベンチマークツールを 走らせる・・・ SCORE 100ぐらい(Ruby)
  22. 22. 次に Ruby -> PHP DBのバックアップ(dump) を実行
  23. 23. SCORE 800ぐらい
  24. 24. チーム内での一言 「PHP優秀じゃん」
  25. 25. ちなみに後から考えてわかったことですが 最初にDBのdumpをとったため DBのデータがキャッシュにのった関係で スコアが8倍のびました 決してRuby->PHPが効いた訳では ありません
  26. 26. DBまわりの チューニング をはじめる
  27. 27. pt-query-digestをいれてもらう (そのあとNewRelicもいれてもらった)
  28. 28. my.cnfどこ 問題
  29. 29. /etc/my.cnfを変更しても反映されない ・・・ とりあえず mysql> set global XXX=xxx で逃げる でもslow-queryのファイルが 吐き出せない・・・
  30. 30. /etcの下を さがす・・
  31. 31. あった! /etc/mysql/mysql.conf.d/mysqld.cnf
  32. 32. ・クエリーキャッシュをON ・とりあえずメモリまわりチューニング - innodb_buffer_pool - xxxx_buffer_size ・php-fpmのプロセス数を1->10へ
  33. 33. あれ・・・
  34. 34. 3,000スコア 越えてる!
  35. 35. しかし・・・
  36. 36. 10分差で 3,000スコア 1番乗りならず
  37. 37. もっと早く やっておけば・・
  38. 38. 気を取り直して
  39. 39. pt-query-digestの 結果を愚直に直す
  40. 40. ・INDEXをはる -> スロークエリチェック  のループ  (カラム数が4つのテーブルに   カラム数3つの複合インデックス   read命みたいなものも作る・・) 結果、0.1sec以上のスロークエリーは0
  41. 41. 遅いページは ・・・・
  42. 42. / HTTP/1.1" 200 17331 "-" "Isucon5q bench" 1.614
  43. 43. / TOPページが おもい!
  44. 44. ここまでで 開始して 3時間くらい
  45. 45. プログラムを 修正する 決意!
  46. 46. PHPは Slimという マイクロフレームワーク でかかれていた
  47. 47. 直した場所!
  48. 48. $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; です。
  49. 49. loop中にSQLを なげるのをやめた
  50. 50. もう1カ所 loop中に クエリーを投げている 場所があったが直せず ※問題の詳細が知りたい方はこちら(http://isucon.net/)
  51. 51. 一旦今の ベストスコアを 作ってみる ※他のメンバーも諸々チューニングしてくれましたが 自分のわかる範囲のみ書いてます
  52. 52. 各種ログを止める ・slowlog ・NewRelic ・xdebug
  53. 53. 結果
  54. 54. 何が足らなかったか
  55. 55. いろいろ足らないのは 承知の上ですが 1つだけやっておけば よかったこと
  56. 56. こたえは 最初にやったこと
  57. 57. DBのdump =(データの キャッシュのせ)
  58. 58. 正しくは次のパラメータ innodb_buffer_pool_dump_at_shutdown=ON innodb_buffer_pool_load_at_startup=ON バッファプールのダンプ、リストアを実施を行う設定
  59. 59. まとめ
  60. 60. オンライン予選 利用言語比率 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組
  61. 61. 本選出場が決まった27チーム Ruby   37.0% 10組 Perl   25.9%  7組 Golang  22.2%  6組 Python  11.1%  3組 PHP    3.7%  1組 未回答   7.4%  2組
  62. 62. 頑張れPHP

×