ISUCON4(2014)予選に参加したのでひとり反省会
最初にさらりとチーム概要について述べ、後半に私ひとりだけの反省を書く。
概要
ISUCON4 予選に @AknEpと@syu_cream そして私(@suma90h)の3人で9/28(2日目)に参加した(リンク先は彼らのブログエントリ。以後も敬称略)。 ISUCONとはご存じの方もいると思うが、ウェブアプリケーションのチューニングコンテストである。
この3人になったのは、仲がよい面子だったので私からtwitterで声をかけてみたという感じ。 2人ともつくばに居た頃から一緒に集まって飯へ行く仲だったのでそのあたりに問題はない。
AknEpはWebアプリを割とフルスタックで仕事をしているみたいで、syu_creamはHTTP/2とかインフラ・OS周り、私はミドルウェア(実装する側)のプロということでチームを組んでみて、最終的なスコアは25000前後(17時時点では19位)で予選敗退。
今回の出場のモチベーションは、私の気持ちとしては 「普段の仕事ではウェブアプリのチューニングをレイヤの上から下まで全部含めてやる機会がないので学習がてら挑戦してみたい」 といったところ。 2人ともそんなもんだと思う。 「あわよくば予選突破」と事前の打ち合わせで話していたけれど、そんなに甘くはなかった。 最終的な感想としては、準備しなかった割に点数取れたし満足という感じである。でもやっぱり悔しいので次はちゃんと準備して点を取りたいね(反省は後半へ続く)。
環境
プログラミング言語にはRubyを選択。
会場は私の部屋(syu_cream, suma90h) + リモートな沖縄(AknEp)だったのでSkypeで音声チャットを使いながら予選に臨んだ。 渋谷という案もあったが、地理的に少し遠いため流れた。
ちなみに、事前に買っておいた Jabra SPEAK 510 スピーカー というスピーカーマイクが活躍してくれたので、音声チャットだからといって大きな不便はなかったように思う。 もちろん、オフラインで集まれるほうが良いのは言うまでも無い。 バッテリー内蔵・Bluetooth接続なので移動もしやすかった。
作業中 pic.twitter.com/lapncNBLyQ
— Shuzo Kashihara (@suma90h) 2014, 9月 28
昼食
あらかじめ出前を取り、やる気の低下を防ごうとした。 食事中は寿司に注意力を奪われることとなった。
結果的には、良い物を食べると元気になるので出前に寿司をとったのは成功だったと思う。次に似たようなコンテストの参加や、集まるときも寿司がいい。
我がチームの #isucon の様子です pic.twitter.com/ebuabhfrKD
— Shuzo Kashihara (@suma90h) 2014, 9月 28
ひとり反省会
AknEpが沖縄にいるため3人集まっての打ち上げは日を改めて行うため、私ひとり分の反省である。
前述の通り、結果的には実力や事前準備無しという条件でちょっとした点数を得られたという意味で満足だがやっぱり悔しい。 反省を読む前に、何をやったかという意味で参考に@AknEp, @syu_creamの2人のブログの作業内容と、予選突破チームのブログ(手法)を事前に軽く読んでおいていただきたい。
ISUCON4 オンライン予選 関連エントリまとめ : ISUCON公式Blog
私の理想としてはチーム「椅子子」の手法と時間・スコアの伸びが手堅い感じで羨ましいと思えた。
チーム「椅子子」でISUCON4予選で2日目5位でした - BLOG::はるかさん
予選内容を知らない人向けのあらすじ
2014年のもう秋に入りかけた頃の話である。 いすこん銀行という銀行のウェブサービスがあった。
諸処のコンテスト予選という事情のため、WebのURL(API)としてはトップページ、ログインページ、ログイン後のマイページの3つのページが提供されていた。 静的なファイルとしては画像1つ、CSSが3つ。 ログイン時にはMySQLに格納されたID, パスワード(ハッシュ)の確認と、これまでにログインに連続失敗していないか(IP BAN)の確認が走る。
詳細は予選突破したコードを公開している人もいるので、そちらを見るとよろしいかと。 AMIも運営から公開されるかもしれません?
時間配分
時間配分と人の担当はかなりミスった。 10:00開始で、18:00終了である。
- 初動がかなーり遅れた
- 16時過ぎにようやく2万点を超えた(2日目のスコアについては3,4万点付近に10位のボーダーラインがあったと想像している)
- それもMySQL, puma(unicorn), nginxの設定込みでであり、残り2時間切った段階で大きくアプリの変更を試す時間はなかった
- 私(suma90h)が連続して暇になった時間があった
- ひたすらRuby/Sinatraのプロファイラを探したり、自作しかけたりしていた。無駄に終わった
作業
- AWS 1インスタンス共有はやめたほうがいい
- 作業の効率化のため複数インスタンス起動や、デプロイ自動などはもっと推進してよい
- 最初からBitBucketでコード, configを管理していたのは良かった
- ただconfigはリポジトリ作っただけで何もコミットしていないのはダメだった点である(追記:コミットはしてたけどgit pushしてないだけだった)
- 後になってRuby sinatraのproductionがオフだったと知った
- これに関しては仕方が無い
伝家の宝刀
インフラ系のエンジニアは暗記してそうなあるあるパターン。
効いたもの
- Linuxカーネルパラメータ:TIME_WAIT 状態への対策
net.ipv4.tcp_tw_recycle = 1
とか- ベンチマークツールがKeepAliveあまりしない仕様だったため、利用可能になるポート番号の枯渇が深刻となる
- 参考に: Linux - ぜんぶTIME_WAITのせいだ! - Qiita
効かなかった・試し忘れた
- Linuxカーネルパラメータ:ファイルディスクリプタ数の制限解除(ulimit)
- サーバやベンチマークツールの利用するソケット数が増えてデフォルトの制限を超えるとソケット作成に失敗する要因となる。今回は出なかったぽい(追記:スコアを3万点台まであげると設定が必要になった)
- jemallocへのメモリアロケータすげ替え(LD_PRELOAD)
- 有意な結果は得られなかった
- 今回はメモリ容量が数GB単位で空いてたので、アプリ側にチューニング入れてメモリを富豪的に使ったら効いたかもしれないし効かなかったかもしれない
- 今回はRuby 2.1だったのでGCが優秀な気もする
- TCP Fast Open
- Linux kernelが比較的新しいものだったため、TCP Fast Openでワンチャンあるかもと思った
- ベンチマークの結果は微々たるもので有意な結果は得られなかった
- 今後、誰か試したりしてレポートして欲しい
- ベンチマークツールのリバースエンジニアリング
- レギュレーション的には制限はなかった
- 競技のキモとなるプログラムであるため、どんな結果が高得点になるのか、またベンチマークツール自体のチューニングが可能かもっと(ブラックボックス)解析するべきだった
- 逆アセンブルまでするのはあまり楽しくなさそう(やってなくて正解)
反省まとめ
- DBMS, nginx, Linuxなどのチートシートは用意しよう
- 競技マシン・ベンチマーク環境は潤沢に
- 思い切ってアプリの全面改装(改造)に挑戦するメンバーがいてもよかった
- ベンチマークツールの振る舞いもよく観察する
- 作戦会議のための準備をする
- 午前に作戦会議やったけど、事前に準備してなかったので行動戦略・指針がなかった
- 自主的に動くのもそこまで悪くはないが、仕事とか一緒にしてないメンバーだったのでお互いに勘所がわかってなかった