フクチ@プログラミングと釣り好き大学生のブログ

プログラミングと釣りと、ときどき日常生活

codebaseで模擬isuconやってきた

 

先日、codebaseで行われてた模擬isuconに行ってきました。

f:id:Yuki-F:20171011125552j:plain

 

 

本題に入る前に軽くcodebaseついてお話すると,

codebaseについて
CODE BASEは、「宜野湾西海岸を、ITビーチに!」という目的のもとプロトソリューションが運営するラボスペース。これからITスキルを身に付けたい方や、すでにエンジニアやクリエイターとして活動されている方が集う場所を目指し、様々な勉強会やイベントを開催していきます。

----HPから引用


以前、訪れて作業していましたが、内装すごく綺麗でした。

f:id:Yuki-F:20171011123725j:plain

isuconを一言でいうと、webアプリケーションを高速化を競う大会です。
具体的にいうと
・事前に与えられたwebアプリケーション(ex,ecサイトとか掲示板などのwebapp)のチューニング
・チューニングが成功した分だけスコアが上がる。そのスコアで競う
・1チーム三人(二人も可)で1組
・制限時間:8h

ってな感じです。

 

で、今年の四月からその出場に向けてチーム組んで勉強していて模擬isucon自体は初めてではなく、今回で6.7回目くらいでした。

ただ、今回は初挑戦のishocon1と事情(別記事で書きます。)があってチームではなく、一人で参戦。

ちなみに
githubhttps://github.com/showwin/ISHOCON1
題材webappは「ishocon」という爆買いecサイト的なやつ。

 

スコアの遷移
ざっくりと僕のスコアの遷移を

1.2017/10/08 10:49:26 Score: 283(初期スコア)
2.2017/10/08 11:47:43 Score: 620( my.cnf調整した)
3.2017/10/08 11:50:38 Score: 573( my.cnf調整2)
4.2017/10/08 12:06:14 Score: 558( unicornのワーカー増やした)
5.2017/10/08 12:09:42 Score: 593(nginx.conf調整)
6.2017/10/08 12:57:34 Score: 2119(historiesのところにindex貼った)
7.2017/10/08 13:36:00 Score: 17235(commentsテーブルのusers_id product_idにindex貼った)
8.2017/10/08 15:37:15 Score: 22838(benchを4にした)
9.2017/10/08 16:36:14 Score: 23948(app.rbのcurrent_userをチューニング)
最終.2017/10/08 18:01:08 Score: 24963(app.rbのcmt_queryとcmt_count_queryをいじった)

最終スコア:24963

おおまかにやったこ


*nginx側
・alp入れてログを解析
・nginx.confの調整

*app側
unicornのworker_processを増やす。
・gitリポジトリつくる。

@ローカル

・isuchon1をローカルで立ち上げる

・rack_line_profでコードごとの処理速度を監視
・rack_mini_profilerでページごとのクエリの数とかかった時間を監視
・上でわかった部分を中心にappチューニング

*DB側
・myprofilerでスロークエリの分析
・my.cnfの調整
・DB上でindexを貼る。
・dump→リストア

こういった準備等や設定ファイルの調整を12:30くらいまでに終わらせれた。

 

そして、ログを見たりしながら
indexをペタペタ作業。これで

5000ms → 200ms 
スコア2万を超えるという。
indexつえぇぇ

 

貼り終わったあとは
14:00すぎくらいからappcation側をチューニング。

今回のapp側のネックとしては
商品とそれに紐づくレビュー、そのレビューの数を表示させる処理をviewsの側でクエリを呼び出していて、それをeachで回していた。

で、それに1h30くらいかけてチューニングするもエラーとかででできず(技術力が足りない)、
他にネックとなっているところを探すと

 def current_user
   db.xquery('SELECT * FROM users WHERE id = ?', session[:user_id]).first
end

このcurrent_userというメソッドが30ms くらいかかっていて、購入ページやコメントページで呼び出されていたのにもかかわらず、一度だけログインユーザーの名前だけを使い、あと、使うのはidだけというw

これを、別でcurrent_user_nameメソッドをつくってsession[:user_id]だけ返すようにしクエリを呼び出さないようにした。

そしたら

30ms → 0.3ms まで下がった。が

スコアは1,000くらいしか上がらなかった。。

ここで残り一時間。。。 

 

最後に悪あがきで

my.cnfとnginx.confをググりながら調整

結果:スコア変わらず。。 

残り10分で

app.rbの中で無駄に多くのカラムを取ってきてるやつを無くしてあげた。

結果:1000くらい伸びる

 

そしてしゅーりょー

 

今回の感想

app側のチューニング、ちゃんと遅い部分を分析して、こうしたら早くなりそうって推測してそれを実行できたのは素直に嬉しすごく楽しかった。

ただ、一番ボトルネックだった部分を直せなかったりとか、スコア、初めて2万超えたけど順位的にみたら、下から2,3番目くらいだったのでそこがすごく悔しい。。。

本番はもっといろんな人と競うことになる。

残り2週間弱でどのくらいのレベルまでいけるかわからないがやりきっていきたい。

 

最後に、プロビジョンの立ち上げやポータルサイト作ってくれたさぼさんを始め、運営のみなさんありがとうございました。