株式会社アカツキの短期インターン Server Sonic 2018 に参加してきた話。
とても楽しかった。
普段は携帯ゲームしたり、作ったり全くしない人ですが…
ちょっとゲーム会社も見ておくべきかなぁという気持ちがあったのと、サーバー高速化するのが楽しそうだったので参加した。(アカツキを知ったきっかけは逆求人)
内容は、2人1組で「8月のシンデレラナイン」というゲームのプロダクトコードを高速化するというもの。
シンデレラナインは Rails で書かれていたが、自分は Ruby も Rails も当日5日前くらいまで全く使えなかったので厳しかった。が、準優勝できたのでまあまあ満足。
参加まで
事前に逆求人で話をしていた。参加までは skype 面接が1回あった。面接では、Rails 触ったことないけど圧倒的プログラミング力があるので大丈夫です!みたいなことを話した気がする。(実際結果だけ見ると大丈夫だったっぽい?)
2週間前くらいにインターンで使う Mac が自宅に送られてきて、環境構築して持っていくというタイプだった。 自分は環境構築の半自動化を達成しているのであまりメリットがなかったけど、必要な人には必要な気がするので好印象だった。
7月の時点では、2週間くらい前から Rails 勉強しようかという気分でいたけど、論文修正なるものに時間を吸われて結局あまり勉強できなかった。(一応最低限のことはやった)
当日朝は、目的地を確認する前に携帯の充電がなくなって、どこに行けばよいかわからない危機的状況の中目黒をさまよう恐怖経験をした。
Mac が USB Type C であったおかげで充電ができて助かったけど、普通に遅刻した。ごめんなさい。
ちなみに同じチームのもう一人はもっと遅刻していて情報系っぽさを感じた。
内容
2日間開催で、1日目の 2/3 くらいは講義、残りは高速化コンテストだった。
- 講義
- 環境構築
- Rails やデータベース関連の基礎知識
- 高速化の際に必要そうな知識
- アカツキでの性能改善例紹介
- 高速化コンテスト
- 「8月のシンデレラナイン」というゲームのプロダクトコードを高速化するコンテスト
- 2人1組のチーム戦
- 5つくらいの指定された API のみを高速化する
- コードにはいくつか低速化改悪がされている
- 得点は各 API のスループットの重み付け和みたいなもので決まる
- github に push するとテストが自動的に走って点数が帰ってくるシステム
- 優勝すると豪華賞品
講義
色々がんばってメモした気がするけど、メモが借りた Mac に取り残されたので詳細は忘れた。
rails の profile の方法を始め、monkeypatch(初めて名前を聞いた…)の方法などを教えてもらった。
ruby あまりできない状態だったけど、だいたいついていける内容で、勉強になった。 (本番では結局 monkeypatch するには至らなかったが.)
大切なポイントは、性能改善のためにはとにかく**計測せよ!**とのことだった。
コンテスト
全5チームで、自分は@nanatuyoshy さんとチームだった。
賞品の Switch がほしいのでチーム名は Switch になった。(自分は Switch 持ってるが)ちなみに、賞品は Switch, PS Pro, Happy hacking, kinesis から選べる。
チーム編成の方法はよくわからないけど、見た感じ Rails ちょっとできる人とできない人ペアみたいな感じが多かった?自分はもちろんできない枠。
1日目
1日目は講義の残り時間でやる感じだった。
プロファイルなどは、講義で教えてもらった rack-lineprof と、rails の n+1 検出してくれるやつ(bullet?)を使ってやった。(たぶんみんな同じ)
自分は Rails できない勢なので、ログを API ごとに Issue に整理して、同時並行で重そうな部分を改善してもらうみたいな感じですすめた。
どれのどこが遅いとかの雰囲気はつかめたけど、まとめたやつは結局最後までほとんど使わなかったので、この作業はあまり意味がなかった感じがある。
この時点では ActiveRecord がよくわかっていなくて、n+1 がなぜ発生しやすいか理解してなかった気がする。
ログをまとめたあとは、select は ruby の select だということや、ActiveRecord の使い方を @nanatuyoshy に教えてもらいつつ、明らかに低速化改悪された感じのあるまずい部分を修正して1日目終了。その後は懇親会があった。
このままでは2日目戦力外な感じがしたので帰宅後即 ActiveRecord の記事を読み漁った。
ActiveRecord 完全に理解した。
2日目
2日目は仕入れた知識をふんだんに使って、n+1 を消そうとし(てうまく行かなかっ)たり、重い箇所の SQL を改善したりといい感じの滑り出しだった。
1日目はエンドポイントごとにログをまとめるとかしていたけど、結局どこが改善できるのかあまり良くわからないのと、面倒だったので2日目は grep
と sort
を駆使して全体から遅い箇所を列挙して、対応箇所を検索してがんばる感じにした。vscode はとても便利。(目 grep 力は不要)
n+1 を一通り除去したり、同じクエリが飛んでいる部分をキャッシュしたりして順調に点数があがった。
まわりはプロばかりな感じがしていたけど、1回目の中間発表では点数1位で、テンションがあがった。
n+1 をひととおり除去すると、DB へのクエリ数が減って、ログがきれいになっていったのが面白かった。
ruby の :=
を理解したり、インスタンス変数を使いこなしたりして(正しいのかよくわからず)クエリの結果をキャッシュしたのがうまく行ったりして楽しい気分だったが、2回目の中間発表(?)では追い抜かれて2位になった。
その後は json のレンダリング部分の改善などいろいろしていたけど、点数が伸びずそのまま2位で終了。
終了後にログを眺めていると、明らかに改善できそうな SQL のログが出ているのに気づいたり、最後に遅いと思ってがんばって改善していた部分よりも遅くて改善できそうな API が残っていることに気づいたりした。
終了後には優秀コミットやネタコミットの発表などがあった。 同じ部分でも他のチームの改善方法が少し違っているなどがあって面白かった。
話を聞いていると、自分たちのチームは大きい部分を抑えられていたけど、優勝チームは加えてかなり地道な修正をたくさんやっていたらしいので、完敗という感じだった。
感想
2日で Rails 使えるようになった(使えない)。
n + 1 が起こっていることをちゃんと認識して修正するという経験は実はしたことがなかったので、良い経験になった。
ログの解析が重要であるというのを身にしみて感じた。2日目はシェル力を駆使して良い感じに実践できたので良かった。
アカツキのオフィスはとてもきれいだった。
優勝したチームの人が ISUCON に出るようなので、ISUCON では勝てるようにがんばりたい。
インターンのために色々と時間をかけて準備していただきありがとうございました。
ここに載せるとよさそうな写真は公式ブログに(写真写り力向上すべきと感じた)
その他
なんかほかの参加者は互いに知り合いな人が多かったらしい?
とあるインターン界隈(?)では @Fumiya_Kume @nanatuyoshy あたりが有名っぽい雰囲気があったけどよくわからない
最近インターンとかイベントの話しか書いてないのでそろそろ技術的な話を書くべく精進します…(Qiita で解決するようなことしかしてない気がする)