半空洞男女関係

思ったこととかプログラミングしてるときのメモとか色々かいてます。メールはidそのままgmail

#isucon 学生予選通過した

ISUCON6id:kwzrid:mimorisuzukoと一緒に「エンボディパイプ椅子」というチームで出場した。結果は学生6位で22,479点。学生の分布を見ると第四集団あたりといった感じ? やることまだまだありましたね…。

前回はid:masawadaid:tyageと出場したのですが結果は振るわず、今回は学生枠の拡大もあってかなんとか予選通過できよかった。

事前準備

事前の準備はid:kwzrが率先して行ってくれて僕らは見てるだけ。サーバーにPixivの社内ISUCON問題とかISUCON4問題を用意しておいてくれたので、それをサークル(id:ncc-log)の合宿で解いたりした。

優勝者層の記事を見ると高度なテクが色々書いてあるけど、いきなりその辺を見ても意味が無い感じがしたのでそのあたりはさほど参考にせず、先ずはできる範囲から学んでいこうと考えた。SQL初心者の留年野郎がISUCON予選通過した方法 - UIUインターン生向けのISUCON CM - Qiita などの記事がレベル的にはちょうどよく、その他大勢のブログ記事を参考にしながら、rack-lineprofとかMySQLのSlow Query機能使ってプロファイリングして、SQL調整したり無駄なところを省いたりプロセス数とかメモリ数調整したりした。

ここでの練習は結構効いていたと思う。過去問は必須。あとid:kwzrがミニマムなdotfiles集を用意してくれていたのもよく、当日快適な環境で作業できたので良かった。これからも使うと思う。

GitHub - kvvzr/tiny-dotfiles

当日

当日は9:00に集合して準備。おもむろに10:00から始まった。時系列順にやったことまとめます。

午前中は慌てる時間じゃない

まずは3人でマニュアルを読みながらデプロイし、全体像を把握することに。とにかく「11:30までは慌てる時間じゃない」ということでやった(案の定id:kwzrはすぐテンパっていた)。最初の1時間は慌てる時間じゃないと誰かが言ってたけど、慣れてない学生なんかは午前中は慌てる時間じゃないという気合でやっていっていいと思う。

それぞれが試す為のリソースグループを別で用意して、三人分の開発環境と、1つの本番環境で合計4つの環境を準備した。僕はrack-lineprofを入れて実行しながらコードを読み、全体の関係やアプリケーションから見たボトルネックを浮き彫りに、id:kwzrMySQLのslow-queryやnginxやkataribeのログを吐かせてそれぞれのミドルウェアから見たボトルネックを発見するという作戦。

並行してベンチマークもやってたけど、レスが遅すぎてFAIL、スコアが安定しない。コードを読んでボトルネックの部分が相当ひどいことが分かっていたので、特に慌てることはなかったけど、それをきちんと把握していたのは僕だけで、結果チームのメンバーを焦らせる原因になってしまった感じがあった。ここは反省ポイント。

ボトルネック

この時点で発見したボトルネックと解決策はこちら。結局、どれも rack-lineprof で発見したボトルネックが主。

  • マイクロサービス化しちゃってるのが重い原因っぽい
    • isutarをisudaにマージしちゃう
  • htmlifyの実装が地獄。キャッシュできるところがいくつかある(正規表現のbuild、keywordのsha1)
    • キーワード登録したときにテーブルの中に入れてしまう作戦はどうか? と思いついたけど、登録する度に全ての文章を直さないといけなくてつらい
    • とりあえずやれる所やって、お昼ごはん食べる
  • OFFSETしてるところは直せそう
    • ただこれはぱっと解決策が思いつかなかったので後回し

昼は id:mimorisuzukoが活躍してトリコカレーを買ってきてくれた。トリコカレーというのは大学近くにあるカレー屋で、カレーのルーがめちゃめちゃ濃厚なのが特徴です。中野におこしの際はぜひお立ち寄りください。

twitter.com

カレー食べながら作戦立てた。

  • id:kwzrはisutarをisudaにマージする
  • id:mactkgはhtmlifyをちまちま改善する
  • id:mimorisuzukoはみんなのGo言語を片手にTour of Goをやる

午後

午後は何度もクエリが走っているところを一つにまとめたりとか、md5の計算をしているところはテーブルに入れちゃうとか小さい作業をした。それぞれの作業合わせて4000点くらいになった記憶。これで3時くらい?一通りやることやったので、どうしましょうという話になり、とりあえず

  • id:kwzrmy.cnf いじったりUNIXドメインソケットに切り替えるみたいなことをする、もう少しログ眺める
  • id:mactkg は静的配信 / Cache-Timeの調整、htmlifyの結果をmemcachedに入れてキャッシュする

という作戦になった。id:kwzrは何かもう少しやってた気がする。

memcachedのキャッシュはどこまでキャッシュするのかっていうのは難しかったんだけど、とりあえずキーワードが更新されたらキャッシュ全消しというシンプルなものを実装してみた。 set_name のconditionも無駄なのに気づいたのでここで直しておいたら、これで点数が20kまで到達した。

このあたりでもう17:00くらいになっていて、一旦再起動とかして提出に備えましょうということにした。

最後に正規表現を毎回コンパイルしていることに気づいたんだけど、時すでに遅しで間に合わなかった。

夜はid:kwzrが聲の形を予約してくれていたので3人で新宿に向かった。時間があったので居酒屋で打ち上げしていた所予選通過していてテンションがあがった。乾杯直前に予選通過がわかったのでかなりめでたい感じだった。

聲の形は良かった。また見に行きたい。

まとめと感想

  • 午前中は慌てる時間じゃない
  • rack-lineprofはやはり便利
  • ボトルネックを解消するためにいかにメモリを活用していくかというのがキモとしてありそう
    • ここを使い出すと、どこでどれくらいメモリを使わせるのかという戦いになってくると思うので、dstatとか見たくなるはずである。
    • このレベルに突入できるかが第二ステップかなという気がする。
    • 余計なプロセス切るとかはこのレベルでやることである。
  • 知見が増えるので学生は全員出るべき
  • id:mimorisuzukoをバージョンアップさせたい

ISUCON6qで学んだこと

  • sha1よりmd5の方が早い(セキュリティの問題はある)
  • memcachedの使い方
  • rack-lineprofの使い方
  • 正規表現| は遅い
    • a|b|cより[abc]。でも今回は使えない。

ブログで学んだこと

出てきた疑問点、知りたいこと

  • memcachedでキャッシュするときの戦略はどうしたらいいのか?
    • とりあえずキャッシュして変更があったら捨てる、なので二回目のビューがないと活きないということになる。
    • 今回のように即時反映が必要なときはどうすればいいのか?
  • Sidekiqのユースケース
    • 結構みんな使っているし早くなりそうな気がするけど
  • Redisの便利な使い方
  • rack-lineprofの見方が完璧ではない
  • Thread.current[:db] ||= のイディオムの意味

ISUCON本戦までにすること

  • 疑問点などをすべてキレイにする
  • id:mimorisuzukoRubyとか色々覚えてもらう
  • 卒研をすすめる(ISUCON本戦数日前に卒論目次/タイトル提出がある)

楽しい時間を過ごさせてもらいました。運営の皆様ありがとうございました。本戦でお会いしましょう!!(pixivインターンの人は居るのかな??)