ISUCON6で学生一位取ってきた
2016/10/28 10:37 追記
ふぉのさんが上げてくれたのでリンク
ISUCON6で学生枠1位取れた時の話.md · GitHub
2016/10/28 10:50 追記
あーちゃんも上げてくれてたものの気づかなかった・・・
リンク。
※やったら長文なので、最後まで読まなくても大丈夫、暇な人だけ読んでね。書いてるうちに長文になっちゃったテヘ
去年と同じく予選の様子から書きまーす。
一応去年の貼っとくね。
さて、今年も去年と同じくチーム名はkstm、チームメンバーは去年と変わらず僕とあーちゃん(@bgpat_)とふぉのさん(@fono09)の三人で出た。事前に決めたチーム構成は僕がDB、あーちゃんがアプリケーション、ふぉのさんがインフラって感じ。かなりバランスの良いチームだと僕は思っている。
言語は去年に引き続きGolang。何もしなくても速いってのと、去年予選突破した言語だし、使いやすくて速くて、並列も書きやすくてなにより速いってことが特徴の言語だ。クロスコンパイルとか他にも特徴があるけど、ISUCONではあまり関係ないので割愛。Golangはいいぞ。
チャットにはSlackを、タスク管理にはTrelloを使った。チームメンバー全員が所属するものづくりサークルkstmでの今の主な手段がこのSlackで、使い慣れている事が大きい。主に参考ページのURL共有とかに使う。Trelloはとても使いやすい。普通はタグ付けとかして使っていくんだろうけど、僕たちは「umaの仕事」「bgpatの仕事」「fonoの仕事」ってリストを作って、そこにぽんぽん仕事を入れていく感じで使った。Slackと連携していて、Trelloでなにかアクションすると、Slackにも通知が行くので、Trelloを常に見ている必要はないようにした。
超適当なタスク管理表の様子 pic.twitter.com/H9LwKh89UN
— bgpat (@bgpat_) 2016年10月22日
ああ、重要なこと忘れてた、エディタはVimです。
予選までにしたことは、主にpixivISUCONで遊んだ練習したことです。INDEX貼ってないテーブルがあって点数伸びて楽しかった。
予選はまず、ふぉのさんの遅刻から始まった。彼のマイクロソフトアカウントで登録していたので、彼が来ないことには始まらない。まあよくあることだ・・・とは言え、どーしようもないので緊急事態としてアカウントのユーザー名とパスワードを送ってもらう。もらったあーちゃんがインスタンス建ててスタート。
コード読んでるあいだにふぉのさん到着。大体読み終わったら方針を考える。あーちゃんが一言。「DB消しましょう」・・・僕の仕事が無くなった瞬間だった。
DBを消すって、起動すらしないって方針もあるけど、僕たちはデータベースは一応動かすが、必要なデータはメモリから取って、ユーザーから送られてきたデータはメモリとDBに格納、それで再起動時はデータベースからデータを全部読み込んでメモリに格納する方針。INDEX貼ったような貼ってないようなって感じだけで、それ以外は特にいじらず、あーちゃんが実装していく横で効率的なデータ構造(基本的にはmapだけど、何をキーとするかで効率がだいぶ変わる)考えて口出してた。
あとISUDAとISTARの統合はほぼ僕がやった。無駄に通信してたので、消すに限る。仕事無くなったので恵んでもらった感じだ。ありがたや。
で、今回のターニングポイント、htmlifyをどーするかだけど、とりあえずGolangで正規表現は超絶遅いってことは有名な事実なので消す方針、replaceだけでなんとかやるって感じにしようとした。だけどただreplaceを順番に適応させていくと、一度変換したものに対してさらにリンクを貼ろうとするので全然ダメ。というわけで、@はあらかじめ@@に変えた上で、一つの単語を@(id)という風に変換して、あとでリンクに変換するようにした。この辺はほぼあーちゃん考案・実装。これが決め手となった。
ふぉのさんはnginxの設定書いたり色んなとこ見て回ったあとは白ご飯炊いてお茶淹れて鯖缶あけてくれてみんなで食べた。インフラ班はこの辺の面倒までみて大変だなと思いました(小並感)。
再起動試験をしっかりとやって終了。ちょっと不安ではあったものの、これ以上どうしようもない。
ああ、今年は落ちたかなーと話しながら終わった。
ISUCONお疲れ様でした!
— 馬 (@Goryudyuma) 2016年9月18日
本戦ダメそうなので、皆さんがんばってください!
で、ちょっと経ってから合格通知。予選学生10位(社会人枠に一枠食い込んでくれたので、9位だけど10位)でギリギリ。今年も渋谷行ける~~って喜んだ。
https://t.co/TplUjCe41C
— 馬 (@Goryudyuma) 2016年9月18日
わーい、本戦決定かな!やったー!@p1o1c1k1y と @fono09 と、チームkstmで出てましたー!
(学生枠が増えてて、一般枠に食い込む学生いて助かった・・・w)
本戦がんばりまーす!
アルゴリズム、競プロでいろんなものに触れてきたつもりだったけど、アホコラは知らなかった。知ってても使えたかどうかは不明だけど、ちょっと悔しい。strings.Replacerは一度使ったことあったのに、本番中思い出せなくてこっちはマジで悔しい。
さて、続いて本戦。
まずは前日(今年も前日かよ!?って全く反省していない感じ)に、ISUCON5Finalの練習をした。あーちゃんがDocker-ComposeFileを作ってくれたので、それで(あーちゃんとんでもなく優秀)。
いつも使ってる鯖がトラブルで動かなくて、僕のwindowsにDocker建てて動かして見たけど、外からつながらなくて、仕方なくファイアーウォール切って(!!)やると繋がったので、三人でやっていました。この練習でもDocker-Compose使ったくらいには、僕たちはDockerに慣れていたので、本戦に活かせた感じです。
本戦当日。
長野駅行ったらいたあーちゃんと一緒に蕎麦食った。予定時間に来ないふぉのさん。相変わらずだなーと思いながらも、僕はスーツケース持ってて、東京で電車乗り換えダッシュできない(したくない)状態だったので、とりあえず予定の電車で僕だけ先行、ふぉのさんとあーちゃんは次の新幹線で行くことになりました。で、渋谷。渋谷駅やたら広くなっててびっくりした。ああ、またヒカリエ来れた~~って喜んで会場入りした。ちょっと待って会場にてあーちゃんとふぉのさんと無事合流。レッドブル飲んでコンテスト開始!
最初の動画から「は?10万ユーザー同時接続?」ってなって、「これどーすんだ」ってなってました。予選の問題ははてなにちなんだ問題だったので、本戦はpixivかなーと大雑把には話してましたけど、まさかこんな形とは・・・って感じでした。コンテストが始まって、最初1時間位はデプロイできない問題にハマってました。会場全体が。運営大変だなーって話ながら、レギュレーション何回も読んでました。コア数を20から10に落としてつなげるようになったとのアナウンスがあり、もう一度デプロイ。これも失敗したけど、その次のデプロイで成功。まずとりあえずベンチ動かして、次にGolangに変えてまたベンチ。DBのインデックス確認とかしてみるも、どうにもおそそうなところが分からない。
静的ファイルあるので、とりあえずNginx入れようという話になったのと、Reactレンダリングを行うNode鯖もあるねって話、あと画像を予め生成しておいて静的ファイルとして配信したいなって話になりました。あーちゃんはJS大好きマンなので、Node鯖見たいと言い出し、ふぉのさんはいつも通りNginxを入れてイジる、じゃあ僕はというと、DBはいじれるところなさそうだしアプリケーションいじるかーってなりました。と言ってもほとんどいじれるところはなく、Strokeをメモリに載せる作業をしただけでした。あんまり劇的な効果があったようには見えなかったけど。それから静的ファイル生成するはいいんだけど、どのくらいの時間なら大丈夫か確かめようとしてSleep入れてみたけど、めっちゃ小さくしても、ベンチでタイムアウトしちゃってダメだなー、これ静的ファイル吐き出してる間にタイムアウトしそうだなーってなりました。あとはコード読んでる間に気づいたDBのインデックス、一個貼りました。それからMySQLが立ち上がっていなくてもGolangのアプリケーションは、MySQLが立ち上がるのを待つ設定を書いときました。再起動試験が重要なISUCONでは必須ですね。
他にチームとしてやったことは、Node鯖でTLS処理してたのが重そうだって、Nginxに処理させて、Node側からは抜いたりしました。それから、Golangのアプリケーションにインスタンス一つ、Nodeの処理にインスタンス一つ、MySQLの処理にインスタンス一つ、Nginxの処理にインスタンス一つ、一つのインスタンスは何もしない構成にしました。この2つが点数を伸ばした要因となったようです。あと、終了二時間前くらいから再起動試験を開始しました。その時点で学生一位取ってたのと、このあと急に点数伸ばせるとは思えなかったこと、去年みたいにFailしてしまうのはなんとしても避けたかったことが理由です。最初にrebootコマンド叩いていって、systemctl enable忘れで立ち上がってこないアプリケーションがあった(気づけてよかった・・・)ものの、二回目はちゃんとベンチ通りました。「再起動試験ってrebootコマンドじゃなくてAzureのダッシュボードからやるんじゃね?」って話になり、Azureのダッシュボードからも再起動試験をやり、「インスタンス1,2,3,4,5の順番に再起動試験やったけど、5,4,3,2,1の順番でやると落ちるかもしれなくね?」って話になってその順番でもためしたり、「MySQLが立ち上がる前にGolang立ち上がったらまずくね?」ってなって前述のMySQL立ち上がるまで待つコードを入れてる話したりしました。ここは本当に念入りにしました。
最後30分であーちゃんが「いま第五鯖何も動かしてないけど、この鯖もNode鯖にすればもうちょい捌けそう」とか言い出しましたけど、全力で止めました。点数上げるためにはたしかに必要だし、あーちゃんなら時間内に作業を終わらせられることはほぼ確実でしたが、ここはISUCON本戦、なんとしてでもFailしたくなかったので。そのあとはベンチの点数のうち最後にしたものが扱われるとの記述により、ガチャしてました。二万点超えたところでもう触らないって決めてフィニッシュ・・・ちょっとしたミスで、結局二万点を少し下回ってのフィニッシュでした。来年はこのミス、なんとしてでもなくします(強い決意)。
どうだろうなー、何位かなー。潜っててスコア表示が止まる17時からガンガン点数伸ばしてきそうだなーって話は結構初めの方からしてました。途中社会人枠含めて一位だったときは特に、「あのチームとあのチームは絶対隠れてスコア伸ばしてくる!!」って話を。学生一位、社会人合わせた全体で5位に入ってて本当に良かったです。
ちょっと大きめの金額をもらっちゃったので、ノートPC買い替えたいと思ってます。まだどれにするか迷い中です。
運営の皆さんありがとうございました!来年もこのチームで頑張りたいと思っています。チームメイトに見捨てられないように精進して、来年も本戦行ってなんかしら賞とるぞ!!!
ここから下はただのチラシ裏の落書き。
最近ブログ更新してないナーと思った。セキュキャンの3日目まではギリギリ更新できてたけど、グループワークも忙しくなって4日目から先は書けなかった・・・。で、実家帰ってもやる気でなくて、ICTSC6ってコンテストでサークルで出て3位に入るものの、僕は知ってることを手順通りにやった(MySQLの見たことあるエラー文を、その通りに直した)ってだけで特に書くことなし。IBMのメインフレームコンテストも名前載るまで(パート2まで)やったけど、それまでもメインフレーム特有の普段と違う手順でいろいろやらないといけなくて、更に問題文も英語になって、更に更に忙しくて、もう無理ぃ・・・ってなってやめた。あとこれ書いてるとき(3日くらい費やしてる。道理で長文になるわけだ)にCODEFESTIVAL本戦出場キメた。けどこれも、やれることやったらなんかギリギリ通ったって感じだ。というわけで、なんだかんだいろいろやってはいたものの、書くのがめんどくさいっていうので書いてこなかったけど、言い訳はここまでにして、今回のは特段衝撃的だったので書こうと思った。
僕は今まで生きてきて、一位と言うものが取れた試しがない。仮に取れていたとしても、それはかなり限られた環境での一位で、全国、全世界にはもっともっとすごい人達がいるとわかってて取った一位だ。そんなの一時的には嬉しいけど、ああもっと上には上がいるんだなってなって終わる。運動できるわけでもなく、頭も特段いいわけではない。何か特別な特技も持っていないし、落ちこぼれの一学生だった。今してるサークル長も、みんなどう思ってるかしらないけど、消去法で選んでも僕になる気がするし、勝ち取ったって感じはまったくない。大学の成績も、めっちゃいいってわけではなく落ちこぼれない程度のものだ。そんな僕が、今回学生枠とは言え、全国で一位のチームに名を連ねる事ができたことが、本当に衝撃的だった。一生無理だと思っていた。もう自分でも何書いてるのか分からなくなって来てるけど、とんでもない喜びだったことを察してほしい。(でも社会人枠の人たち倒さないと本当の一位とは言えないよなーってちょっと思ってる・・・無理・・・)。
次もがんばるぞ!
セキュリティ・キャンプ全国大会2016参加記 その二
三日目
3-A【Webアプリケーションの脆弱性の評価と発見】
もう使われていない古いバージョンのサイボウズオフィスの脆弱性を探す会
ひたすら「これは見ていいものなのか・・・?」と思ってた・・・ので、詳しくは書けません・・・
CVSSv3なる方法で、脆弱性の分類をして、重要度をきめるらしい。
・・・が、意外とあてにならないものもあるらしく、重要度は低いけど早急にやらないといけないものも多いらしい。
.htmlの中にif文があって驚いたが、10年以上前のものも含まれてるそうなので、闇が深い。
4-A【クラウドセキュリティ基礎】
クラウドでなにができるようになったか?
-> サーバーをポンポン産んだり殺したりすることが可能となった。
-> サーバーはペットから家畜へ。
ここでもCVSS。やはり重要らしい。
AWSでサーバー立てて遊んだりハンズオンしたりした。
5-A【サーバ運用におけるパスワード管理】
100台サーバーがあって、4人管理者がいたら、理想は400個のパスワードがあるべきだが、実際にそんなこと出来るの?って話。
まあ無理なので、じゃあどうしようか。
とある会社で使われているシステムの説明などをしてくださり、とても面白いと思った。
企業プレゼン
なんか正直良くわからなかった・・・
データを分散して、全部合わさらなければ元データは取り出せないので安全ってのはわかった。
これを用いると、仮にPCをなくしたとか言ったトラブルでも、データをとられることはない。
でも、復元できなくなるので、重要な情報はどうすればいいのか。質問してる人もいたが、回答がなんというか、理解できなかった。
グループワーク
順調・・・なのか?
デスマしそう・・・?
ハニーポットハンズオン
お話聞けてよかった、あんな世界もあるんだ。
ちょっと立ててみたいと思ってしまった。
三日目終わって
ああもう折り返しか、楽しいなあ、もっとやりたいなあ!
セキュリティ・キャンプ全国大会2016参加記
メモ代わりに残していたものを、ちょっと時間あるので公開。
時間あるときに追記します。
セキュキャン参加記
1日目
特別講義1
「トレンドマイクロ」、「カスペルスキー」などと一緒に、インターポールに協力している会社。
どのようにして入りこんだか?
->事例を効果的に見せることで、印象をあげた
印象大事!
人とのつながり大事!!
特別講義2
警察の人
犯罪とは?バレなきゃいい?
グループワーク
チーム名
三対一
読み方
イーマックスのかち
Vim負けちゃったよ・・・
題目
子供の倫理観をどうやって育てるか?
一日目終わって
twitter.comセキュキャン、キャンプという名目で会場内に引きこもれるのマジでいい。許可なし外出の禁止とか、軟禁状態なとことか、引きこもり気質のある人にめっちゃおすすめ。
— 馬@seccamp (@Goryudyuma) 2016年8月9日
twitter.com軟禁状態かつ部屋は快適に冷房効いてて、三食ご飯出て、睡眠時間も程々に与えられてて、めっちゃ勉強するだけでいいとか、ここは天国かよ。
— 馬@seccamp (@Goryudyuma) 2016年8月9日
もしかしてこのキャンプ、最高では?
二日目
1-A【HTTPプロキシ発展】
burp楽しい!Javaはめんどくさいけど、通信の中身を読みやすくしたり自動書き換えしたりできる!
最後の課題、分かったのにPCが不調で・・・。答えはあってたっぽい。また解いておく。
2-C【人工知能とセキュリティ】
(どう違うのかというとうまく説明できないけど、機械学習はめちゃくちゃ頑張れば手がぎりぎり届きそうだけど、人工知能はどうがんばってもまだ無理って感じ。)
1
データから特徴を抽出することは機械学習で可能だが、その抽出した結果を見て判断する、しきい値を決めるのは人間である。
しきい値そのものを機械学習しようとしたところで、その先もまた人間の手が必要となる。(この結果はいい結果か悪い結果か?など)
2
機械学習ハンズオン
TensorFlowを用いた画像分類の学習。コードも短く、簡単にできそうな印象。
3
学習した結果、暴言を吐きまくるbotができてしまった。
-> 悪いデータに汚染されないように、どうすればよいか?
人間が判断して間引けば良い
悪意を持って学習させる人は少数派という仮定のもと、学習させるのは全データの内から幾つか抽出して学習させる。
事前学習の重み付けを大きくして、自由な学習の重みを下げる
CTF
辛さしかなかった。
RasPi二台持ってて、どちらもRaspbianで、パスワードも朧気ながら覚えてたのに「まさかそれはないだろ~ww」なんて思うのはホント駄目。
CTFと自分、相性めっちゃ悪いなーと。なにもかもエスパー問題に見えてもう無理という感想しかない。
一対三(ヴィムのかち)に負けたのは、三体一(イーマックスの勝ち)の一の方のVim派の自分としては嬉しいやら悲しいやら複雑。
二日目終わって
速攻で部屋帰って寝た。もうここに住みたい。
ICPC2016国内予選参戦記
チームUSAで出場、AとBとCの三問といて61位でした。チーム名の由来はチームメンバー(うま,ゼレ(selee),あーちゃん)の三人の頭文字。
予選開始前
練習問題のJ,K,Lをあーちゃんが通してた。その後別チームのわにさんが「Mの解法思いついた」とか言い出して通してた。で、なんか僕に伝えてきたので僕も通しといた。自分で思いついた訳ではないが4完。
予選開始
作戦としては、僕とあーちゃんで速攻でAとBを通し、その間にCをゼレ氏に読んでもらう。で、AとBを通した頃にはゼレ氏がCの問題を把握していて、解法も思いついてたらいいなーって感じで。このチーム、考察力がかなり低めなので、D以降は解ける問題があれば解く的な感じでした。あと、一番コードを書くのがうまいあーちゃんが基本キーボードを触り、僕とゼレ氏は見て間違いを指摘するようなチーム編成です。そのため、使ったPCはゼレ氏のものだったが、.vimrcの設定などは全部あーちゃんのもの。
A
sortして差を見ていって最小値を選ぶだけ。なんか解法というよりコードをそのまま口で言ってた。それをあーちゃんに打ってもらってた。
B
投票する、sortする、残りの票が二位の人に入った場合、1位の人を抜けるかどうか判定、抜けなくなった時点で確定。そこそこスムーズに通せた。
C
愚直解を回した。ゼレ氏が問題読んでくれて把握まではしてくれていたので、問題本文をしっかり読んだのは予選終わってからだった。解法はいいアルゴリズムがぱっと思いつかなかったので、「とりあえず回そうか」的な。最初書いたものは毎回mをループの初期値にするというコードでめちゃくちゃ遅かったが、前回埋めた数字より小さいことはないので、その埋めた数字を初期値とするというコードにしたら結構早く終わって、AC。
D
解けず。奇数番目と偶数番目が同時に抜けていくので、二部マッチングっぽいなーって話をしていた。区間DPで解くのが正攻法だったっぽい?来年までに要復習。
E
解けず。模擬国内BのC問題で出た座圧+imosを三次元でやるのかなー、でもこれだとくっついた物体が2つ以上ある時どうやって分割すればいいのかな、わからんな、とか考えてた。
F
解けず。UnionFindでグループ作っていくのはいいけど、その後どーすりゃいいのかわからなかった。
G,H
一応目を通しはしたが、ぱっと思いつきそうではもちろんなかったのでパス。
以上です。大学内1位は取ったけど、それだけでした。来年頑張ります。
今乗っている路線をなめらかに表示させる
作ったもの
ソース
動機
前に同じようなの作ってて、でも満足はしてなくて、その後某駅○モにも前作と似たような実装で表示されるようなやつができたとの話を聞いたので、じゃあ僕はもっとなめらかなすごいやつ作ってやるぞ!ってなって今作を作った。(たぶんn番煎じ)
使った技術
ubuntu+さくらVPS+NGINX+PHP7+MySQL5.7+React.js+bootstrap
ubuntu
雑魚なのでまともに触れるのubuntuだけ・・・
さくらVPS
前に使ってたVPSより性能高くて反応もよくて非常に満足。ただし高い。
NGINX
配信用。Let's Encryptも使ってHTTPSとHTTP2の対応。ついでにIPv6も対応させた。
PHP7
API用スクリプト。適当に書くだけで動くから好き。PHP5でもたぶん動くけどPHP7にしたのは趣味。
MySQL5.7
位置情報とか駅情報などを入れてるDB。MySQL5.6から導入されたgeolocation型や、MySQL5.7から導入されたJSON関数などを使用している。
React.js
JSの先生に勧められるがまま勉強したフレームワーク。時々詰まることもあったけど、日本語資料が多く調べやすかった(たまに英語資料だがわかりやすい)。画面更新処理などがとても書きやすい(、けどJSのフレームワークこれくらいしかしらないので、もっと書きやすいやつは探せばあるのかも?)。日本語チュートリアルや、koba04氏の一人React.js Advent Calendarがとても参考になった。
bootstrap
Viewを整えるやつ。React-Bootstrapを使った。
データ
国土交通省国土政策局国土情報課国土数値情報ダウンロードサービスの国土数値情報鉄道時系列データから取ってきた。国交省(と気象庁)は手軽にデータ数が増えないそこそこ多めのデータが手に入り、データベースの勉強に最適だと思う。(Twitterなどはリアルタイムにデータが変わるので、初学者にはつらい可能性?)
今後
気が向いたらPHPのAPIを書き直すかもしれません。(現状の実装がとても汚いことは自覚している・・・)
あと、もっと機能付け加えた方がいいのかな。シンプルイズベストで、今の感じが結構気に入ってるけど、やる気が起きてアイデア浮かべば実装するかも。
感想
ひとりISUCON、つらいけど楽しかったです() ISUCON6も決勝頑張っていきたいと思います!
謝辞
協力してくれたものづくりサークルkstmのメンバー達、様々な情報を提供している先人達、データを公開している国交省の人達、その他何かしらで関わってる人達、感謝です!
供養
この作品は前作の全面改修でもあります。もう使われることは無いと思うので、ここに残しときます。
前作ったやつ
それのソース
ひどさ
JSがわからなくて、PHPでJSのコード生成してたりする。と聞くだけで想像する方法とはたぶん違う方の生成。どうしても詳細が知りたかったらソースみて。うんコードが大量にある。見ない方が幸せ。
動機
電車に乗っているときに、今乗っている路線の情報とか取得できたらおもしろそうって思った。ただしこの前作では、新幹線など駅間が長いところに乗っていると、横の在来線に乗っている判定がされることが多々ある。(今どの路線に乗っているかの判定が再近隣駅から判定しているため。)
さらば
まともに書いた初めてのwebアプリよ、さらば。
ISUCON参戦記
うまです。
ISUCON参戦したので、参戦記を書きます。
チーム名はkstmで、学生枠での参加です。インフラ周りのふぉのと、司令塔のあーちゃん、お荷物枠の僕の三人で参加しました。全員ものづくりサークルkstmのメンバーです。チームの団結力は高いほうかと思いますが、共通言語がないのが問題点です。
まずは予選から。
githubに一応ログを残しています。
様々な事情から、予選の練習を開始したのが前日の夕方頃からで、練習不足感甚だしいしかも寝不足の状態での予選でした。少し触ってみて決めたことは、ISUCONで使える言語の内、ふぉのはPerlとRubyがある程度読めますが、インフラ周りを見ることに徹するのでその2つはボツ、あーちゃんはJavascript大好きなのでNode.JSが使え、PHPもかけます。僕はPHPとGolangがスコシヨメルですが、たいして書けません。しかしPHPはバリバリにフレームワークが使ってあり、その知識もないと見るのは厳しそうだと判断し、優先度を下げました。よって担当割当はnginxなどをふぉの、サーバープログラムをNode.JSであーちゃん、SQLを僕が担当することを事前に決めました。
少し仮眠を取り、サークル部屋に集合。本番開始直前に開始の一時間の遅れとNode.JSの実装がないこと、さらにPHPがエラーでうまくいかない可能性があること、付け加えてGolangも点数が出ない事が判明、大慌てで言語の変更を迫られました。とりあえず過去問を見たところ、GolangならSQLクエリも読みやすく使えそうだとの判断で、僕はSQLを読むのをGolang実装で読むことにし、サーバープログラムはとりあえずGolangでやってみて無理そうならその時考える方針で開始しました。
とりあえずインスタンス起動して初enqueue、たいして性能でずGolangに変更してenqueue、0点を記録してからの滑り出しでした。僕とあーちゃんはちょっと長めのコードだったのでひたすらコメントを付けて回りました。その間にふぉのさんが改善してくれて600点ちょいを出せるようになりました。このあとはひたすらこの時に書いたコメントに従ってコードの改善をしていくことになります。なにしてるかよくわからなければコメント書いとけばなんとかなる・・・こともある・・・。僕は頭があまり回っておらず、構造把握は殆どできてない状態でしたが、あーちゃんに言われるがままやっていました。まともに改善したのはN+1問題のクエリ一つだけと、SQL担当とはとても思えない結果でした(お荷物枠の力発動!)。それからGolangを一年ほど前に少し書いただけというあーちゃんにGolangの仕様を聞かれたら答え、わからなければggって答えと、そんなことをずっとしていました。apt-get upgradeの罠をたまたま回避できたり(誰かしてるだろと思って僕はしなかった)、謎のタマキさんには出会わなかったり、最後どうしても時間内に改善できなかったLIMIT 1000を100に変えたりキャッシュつけたりいろいろした(主に僕以外のメンバーの頑張りの)結果5000点以上上がったり、再起動後のジャッジの点数ではなく最終ジャッジの点数が取られたことなど(再起動試験は行っていたが、不安要素満載だった。failしてても文句言えない・・・)と、大変運にも恵まれていました。最終スコアは7898と学生枠3位での通過となりました。この本戦通過の通知は、サークルバーベキュー大会が終わって直後のサプライズになったことを記しときます。
そして、昨日の本戦。もちろん練習時間は験を担いで(?)ほぼ一日、これまた練習不足での本戦でした(反省しろよ!!)。朝の長野駅集合で新幹線で東京は渋谷ヒカリエまで。北陸新幹線かがやきはとても速くて快適ですね!堪能して山手線で渋谷まで。開場40分前に集合場所についてリラックスしていました。開場し、かっこいい参加者を示すカードが貰えてLINEオフィスまで。カードにはtwitterアイコンをそのまま提出したのですが、もっとまともなアイコンを使えばよかったと少し反省。会場に到着して、最初は景色のいい窓際のソファ席をチョイスしたのですが、机が低く狭く、あまりやりやすい環境ではなさそうだったので机席に移動。長机も1つ借りてとても良い環境でコードを読むことができました。周りに強い人がたくさんいる中での緊張感を味わえてよかったです。
さて、本戦ですが、結果から言うとfailの0点でした。いくら時間がなくとも慌てていようとも天地がひっくり返ろうとも、再起動試験だけは絶対にするべきことだということをまず書いておきます。ただ、半数以上のチームがfailで落ちていました。もう一度書きます。再起動試験は絶対にやるべきです。
内容はAPIをいかに効率的に叩くか(まとめすぎ?詳細はggってください)というやつでした。予選と同じ体制で、Golangを選びました。とりあえずubuntu14.04の3コアCPU4GBメモリ*3という構成だったので、ubuntu14.04のapt-getで標準で入るGolang1.3(←今は違うかも?)でapp.goがコンパイルされている可能性があったので、Golang1.5に上げてくださいと提案。インフラ周りの改善とGolang1.5によるコンパイルで10000点を少し超える点数を出し上位陣の仲間入り。司令塔のあーちゃんから「dataが明らかに遅いです」ともらったので、そのあたりを読みました。何が遅いかすぐには気づけなかったのですが、よくよく読んでみると何回もAPIを叩いていることが判明。ここでの改善案として、1,Golangお得意の並列化をする、2,redisにクエリ結果をキャッシュするの二点を考えました。並列化を実装してみたのですが、なぜかエラーで落ちる。クエリ結果をキャッシュする方も、キャッシュしていいやつとしてはダメな奴があり、途中で気付いて分けていたりしたのですがなぜかfail連発でダメ。ブラウザから見ると正常に動いているように見えるのですけどね。そこそこのコードを書いたり消したりしましたが、結局コードとしては余り貢献できませんでした。並列化もしていいやつとダメな奴、クエリ結果のキャッシュもやっていいやつとダメな奴があったっぽいです。もっとちゃんとAPIの仕様を調べておけば回避できたかもしれませんが、考察できたかどうかは未知数です。並列化してはいけない奴、キャッシュしてはいけない奴に気づけなかったので、どこかコードが間違っているんだろうといろいろ書きなおしたりしてたのですが、点数はfailになるか下がるかのどちらかで、大した改善はできませんでした。もっと自分の書いたコードに自信を持つことはもちろんのこと、APIは並列で一斉に叩けばよいわけではないことを学びました。
本戦終わっての結果発表、今年は学生賞は該当なしでした。学生枠全チーム再起動試験で落ちたっぽいです。過去の自分に伝えることができるなら、「本戦始まったら一切PCに触れるな。そしたら学生賞は取れるぞ」と教えてあげたい・・・。一位のfuziwara組には脱帽です。どうやったらあんなにすごい改善が実装できるのか。すごすぎです。
ISUCON参戦記は以上です。お荷物枠になってしまいましたが、来年はちゃんと活躍して本戦に行けるように、一年間精進します。
@Goryudyuma