サイバーエージェントのBackend Tuning Competitionに参加しました

6月の7、8日にサイバーエージェントのBackend Tuning Competitionというインターンに参加してきました。 形式としては個人戦のISUCONのようなもので、2日間にわたってサーバサイドの実装やDBなどをチューニングしてスコアを競うというものです。 そこで自分がやったことなどを書いておこうと思います。 1日目 言語の選択 最初にプログラミング言語を選択するコマンドが用意されていたのでそれを使って使用言語の選択をしました。 選べる言語はGo, PHP, Node.js, Javaで僕は普段から使い慣れてるGo言語を選択しました。 この時点でベンチを回してスコアを計測したら750くらいでした。 プロファイリングの設定 DBやNginxのログ解析のための設定をしました。 以下のサイトを参考にツールなどを設定。 DB周りの解析 https://nishinatoshiharu.com/mysql-slow-query-log/ Nginxの解析 https://nishinatoshiharu.com/install-alp-to-nginx/ 周りの人はpprofなどを使って華麗に解析してたみたいなのですが、僕は導入することができなくて諦めました。。。 gitの管理など いじっていてコードが消えたら怖いのでレポジトリをgitで管理する設定をしました。 そこでローカルに落として作業するか迷ったんですが、結局VSCodeのRemote SSHを使ってコードの編集はしました。 N+1問題の解決 アプリケーションのコードを見てN+1問題が発生してそうなところの修正を行いました。 しかし修正をしたのですがスコアは全然変わりませんでした。 ここで集中が途切れたので「小説家になろう」で俺TUEEE系の小説を読んで精神統一をしました。 インデックスを貼る N+1問題を解決しても速くならなかったので無心でインデックスを貼り続けました。スロークエリログやNginxのログを見てボトルネックになってそうなクエリにインデックスを無限に貼り続けました。 この作業をすることでスコアが1500くらいになった気がします。ずっとスコアが変わっていなかったのでかなり安心しました。 強敵の出現 全てのクエリにインデックスを貼ったのですが、一つだけインデックスなどを貼っても一生速くならないクエリがありました。 SELECT article_id, count(user_id) as iineCnt FROM iines WHERE updated_at >= DATE_ADD(NOW(), INTERVAL -1 MONTH) GROUP BY article_id ORDER BY iineCnt DESC, article_id DESC LIMIT 5 これの解決方法を2時間くらい悩んだのですが全然解決できません。 そこで息抜きにISUCONの解説記事などを読んでいました。するとキャッシュに関する記事が大量にあったのでこいつもキャッシュで解決できるのではないかと思いやってみることにしました。 結果、めちゃくちゃスコアが上がりました。確か2000を超えた気がします。1位だったので調子に乗ってすぐにツイートもしてました(間違えてこのツイート消してしまった。。。)

Read More