isucon4 予選参加記

下記イベントの参加記です.

優勝賞金100万円!今年もやります 第4回 ISUCON 開催と日程のお知らせ #isucon : ISUCON公式Blog http://isucon.net/archives/38857424.html

去年と同じように一日目に「パイの実g」で参加していました. 予選の問題詳細の記事出たらリンク追加予定.追記しました.

ISUCON4 予選問題の解説と講評 & AMIの公開 : ISUCON公式Blog

http://isucon.net/archives/40724693.html

結論

Score: 2677

実装に失敗して初期状態で動かしたベンチのスコアがそのまま結果となっています.

箇条書き

ここの記述はチームというより自分の考えのみを記述しています.

自分の簡単なスキルセット

  • 主にコード書く人
    • Go まあ読み書きできる
    • PHP まあ読み書きできる
  • サーバ構築とかは趣味で軽くやるレベル
    • 金がないので AWS の知識はほぼない
  • isucon とかチューニンガソンとか出たことある

開始前

事前に考えていた戦略

  • 基本 Go で最悪 PHP を使う
    • Go
      • たぶん早い
      • ただでかい修正入れるほど習熟してなさそうなのでやるならちまちまコード変更程度でがんばるぐらいでしょう
    • PHP
      • 大きな改善点見つからない場合ノウハウみつかりやすいのでちまちまコード最適化したりパラメータいじって戦えるかなと
      • Phalcon 書き換えならできなくはないので検討
  • 重そうな修正を時間的に早めにやって終盤軽めのを選んでやる
    • ミドルウェアの設定とかはわりとノウハウ転がってるので最悪コピペすればよさそう
    • 早めに着手すると固執したり実装によっては無意味になる可能性があるのでできれば後のほうでやりたい
  • キャッシュ出来るところはする
    • 去年の isucon やチューニンガソンなどの教訓
  • ベンチのオプション確認する
    • 去年 isucon で workload の存在に気付かなかった教訓
  • バージョン入れ替えとかは余裕があればやればやるけど多分そんなスキルはなさそうのでやらない
  • できれば人数分インスタンス立ててそれぞれやったほうが効率良さそう
    • AWS クーポン来たのでそれの範囲内でやるために 1 台で考えることにした(若干敗因理由)

開始後

確認時やったこと

  • アプリ触る
  • query.log で全部出して 傾向見る
  • slow_query.log でチューニング部分に当たりをつける
  • コード軽く読む
    • 自分は手元に PhpStorm があったので挙動把握は php 読んでた
    • どこかキャッシュ使えないかなとか

簡単に確認した後の感想

対象アプリ触って

  • フィッシングサイトっぽい
  • 見る感じページは二つでログインフォームとログイン後フォームっぽい
  • ログインフォームは失敗時にフォームのページに戻ってきてエラーメッセージ出すっぽい
  • ログイン後になんか動的に出力するものがあるページを表示するっぽい
  • ベンチ走らせてなくても isucon-bank.png の画像取得に成功したり失敗したりするなぁ(勘違い?)

改善に関して

  • Go は martini かー 知らないなー フレームワーク重そうだなー
  • テーブル少ない( users と login_log の二つ) 簡単に手は入れられそう
  • ユーザの追加などの更新はない オンメモリにできる?
  • login_log の INSERT 重い 消したい
  • テンプレート少ない キャッシュしやすい? と思ったけどログイン後の情報必要なので無理かなぁ.

感想から簡単な戦略

Go 使うかー

軽 中 重 で自分の感覚でコストを考えつつ打てる手を考えた結果

  • (軽)テーブルやカラムは少ないためインデックスなどのチューニングはさくっとできそう
  • (中)ユーザ情報はオンメモリにできそう
  • (重)INSERT なくそう
  • (軽)静的ファイルをフロントでうまく返そう

無視

  • Go のフレームワーク変える(というか外す) -> 今のスキルじゃバグ無し変更はたぶん無理

方針決定後

当初の予定通り重いのからやろうとしたので INSERT なくすあたりに手を出す. (終わったらミドルウェアの設定やるつもりだった.)

作業内容見積もり

  • コード読んでテーブル設計する
    • users に最終ログイン情報突っ込む
    • BAN の ip と user は別っぽいので ip でテーブル作る
  • 変更したテーブルに合わせてコード変更する
  • テーブル変更に対応した初期化スクリプト

担当分担

ここらへん記憶が曖昧

  • 初期化スクリプト書く人
  • コード変更する人
  • コード変更する人 && 方針が正しいか検討する人

作業

ハマった所

  • 初期化スクリプト
    • webapp のライブラリを使いまわそうとするも失敗してて時間食ってた様子
  • BAN 対象の ip や user の決定方法
    • コードが結構わかりにくかった
      • クエリ複雑
      • コピペミスでわざとバグっぽい書き方してるのかと勘ぐる (rowsB 作った後に rows 参照してるあたり)
    • テーブルに存在しない login(カラム名) は必要なのかどうか
      • たぶん要らないと判断
  • BAN 対象の ip や user の更新
    • SQL 間違いまくる
    • (ここの修正ができなかったため 0 点)
  • last_login 情報
    • なんで limit 2 してる?
      • ログイン情報がないときに今ログインした結果を使うためか!
    • /mypage じゃなくて /login 時にいろいろ session にもたせるようにしよう
      • session に入れた値がテンプレ側で nil になり panic
  • martini
    • よくわからん
  • /report の並び順ってなに?
    • 多分 primary key 順なんだろうけどよく調べてないのでなんでもいいものと決めてかかる
    • 正しい判断かどうか不明

結果

Score: 2677

いろいろ対応した環境が正しく動かなかったため初期状態のスコアがそのままとなりました. 以下は予選終了の時点での状態です. ami 公開されたら他の参加者のやりかたとかみながらバグ修正したい

  • 表示上の Score: 17000
  • /report の結果が正しくないのでスコア 0
  • nginx や mysql の設定まったく未修正
  • そういやインデックスも全く手をつけてない
  • 最終ログインの情報と BAN 情報とログイン失敗回数を users にもたせる修正
  • BAN 対象の ip を確保するテーブルの作成およびBAN 情報とログイン失敗回数をもたせる

反省的な(初歩的)

  • 実質 13:00 ぐらいから活動開始してたのでもっと早く起きましょう
  • AC アダプタ忘れないようにしないと電源きれて他の PC 使うとき打鍵感とかキー配列違うのはやばい
  • クーポン来たのでインスタンス一つしか立てなかったけど勝つ気なら人数ぶんインスタンス合ったほうが良さそうね
  • 一人が作業中にちょっと改良的なもの全然できなかったし
  • 一つのユーザとかだと複数人で同じユーザだと vim で死ぬとか素の vim かわからん謎の挙動とかつらいね

最後に

参加者のみなさんお疲れ様でした! 運営のみなさんありがとうございました!