読者です 読者をやめる 読者になる 読者になる

ISUCON6で学生一位取ってきた

2016/10/28 10:37 追記

ふぉのさんが上げてくれたのでリンク 

ISUCON6で学生枠1位取れた時の話.md · GitHub

2016/10/28 10:50 追記

あーちゃんも上げてくれてたものの気づかなかった・・・

リンク。

bgpat.hateblo.jp

 

※やったら長文なので、最後まで読まなくても大丈夫、暇な人だけ読んでね。書いてるうちに長文になっちゃったテヘ

去年と同じく予選の様子から書きまーす。

一応去年の貼っとくね。

 

goryudyuma.hatenablog.jp

 

さて、今年も去年と同じくチーム名はkstm、チームメンバーは去年と変わらず僕とあーちゃん(@bgpat_)とふぉのさん(@fono09)の三人で出た。事前に決めたチーム構成は僕がDB、あーちゃんがアプリケーション、ふぉのさんがインフラって感じ。かなりバランスの良いチームだと僕は思っている。

言語は去年に引き続きGolang。何もしなくても速いってのと、去年予選突破した言語だし、使いやすくて速くて、並列も書きやすくてなにより速いってことが特徴の言語だ。クロスコンパイルとか他にも特徴があるけど、ISUCONではあまり関係ないので割愛。Golangはいいぞ。

チャットにはSlackを、タスク管理にはTrelloを使った。チームメンバー全員が所属するものづくりサークルkstmでの今の主な手段がこのSlackで、使い慣れている事が大きい。主に参考ページのURL共有とかに使う。Trelloはとても使いやすい。普通はタグ付けとかして使っていくんだろうけど、僕たちは「umaの仕事」「bgpatの仕事」「fonoの仕事」ってリストを作って、そこにぽんぽん仕事を入れていく感じで使った。Slackと連携していて、Trelloでなにかアクションすると、Slackにも通知が行くので、Trelloを常に見ている必要はないようにした。

 

 

ああ、重要なこと忘れてた、エディタはVimです。

 

予選までにしたことは、主にpixivISUCONで遊んだ練習したことです。INDEX貼ってないテーブルがあって点数伸びて楽しかった。

 

予選はまず、ふぉのさんの遅刻から始まった。彼のマイクロソフトアカウントで登録していたので、彼が来ないことには始まらない。まあよくあることだ・・・とは言え、どーしようもないので緊急事態としてアカウントのユーザー名とパスワードを送ってもらう。もらったあーちゃんがインスタンス建ててスタート。

コード読んでるあいだにふぉのさん到着。大体読み終わったら方針を考える。あーちゃんが一言。「DB消しましょう」・・・僕の仕事が無くなった瞬間だった。

DBを消すって、起動すらしないって方針もあるけど、僕たちはデータベースは一応動かすが、必要なデータはメモリから取って、ユーザーから送られてきたデータはメモリとDBに格納、それで再起動時はデータベースからデータを全部読み込んでメモリに格納する方針。INDEX貼ったような貼ってないようなって感じだけで、それ以外は特にいじらず、あーちゃんが実装していく横で効率的なデータ構造(基本的にはmapだけど、何をキーとするかで効率がだいぶ変わる)考えて口出してた。

あとISUDAとISTARの統合はほぼ僕がやった。無駄に通信してたので、消すに限る。仕事無くなったので恵んでもらった感じだ。ありがたや。

で、今回のターニングポイント、htmlifyをどーするかだけど、とりあえずGolang正規表現は超絶遅いってことは有名な事実なので消す方針、replaceだけでなんとかやるって感じにしようとした。だけどただreplaceを順番に適応させていくと、一度変換したものに対してさらにリンクを貼ろうとするので全然ダメ。というわけで、@はあらかじめ@@に変えた上で、一つの単語を@(id)という風に変換して、あとでリンクに変換するようにした。この辺はほぼあーちゃん考案・実装。これが決め手となった。

ふぉのさんはnginxの設定書いたり色んなとこ見て回ったあとは白ご飯炊いてお茶淹れて鯖缶あけてくれてみんなで食べた。インフラ班はこの辺の面倒までみて大変だなと思いました(小並感)。

再起動試験をしっかりとやって終了。ちょっと不安ではあったものの、これ以上どうしようもない。

 ああ、今年は落ちたかなーと話しながら終わった。

 で、ちょっと経ってから合格通知。予選学生10位(社会人枠に一枠食い込んでくれたので、9位だけど10位)でギリギリ。今年も渋谷行ける~~って喜んだ。

 アルゴリズム、競プロでいろんなものに触れてきたつもりだったけど、アホコラは知らなかった。知ってても使えたかどうかは不明だけど、ちょっと悔しい。strings.Replacerは一度使ったことあったのに、本番中思い出せなくてこっちはマジで悔しい。

 

さて、続いて本戦。

まずは前日(今年も前日かよ!?って全く反省していない感じ)に、ISUCON5Finalの練習をした。あーちゃんがDocker-ComposeFileを作ってくれたので、それで(あーちゃんとんでもなく優秀)。

github.com

いつも使ってる鯖がトラブルで動かなくて、僕の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本戦出場キメた。けどこれも、やれることやったらなんかギリギリ通ったって感じだ。というわけで、なんだかんだいろいろやってはいたものの、書くのがめんどくさいっていうので書いてこなかったけど、言い訳はここまでにして、今回のは特段衝撃的だったので書こうと思った。

 

僕は今まで生きてきて、一位と言うものが取れた試しがない。仮に取れていたとしても、それはかなり限られた環境での一位で、全国、全世界にはもっともっとすごい人達がいるとわかってて取った一位だ。そんなの一時的には嬉しいけど、ああもっと上には上がいるんだなってなって終わる。運動できるわけでもなく、頭も特段いいわけではない。何か特別な特技も持っていないし、落ちこぼれの一学生だった。今してるサークル長も、みんなどう思ってるかしらないけど、消去法で選んでも僕になる気がするし、勝ち取ったって感じはまったくない。大学の成績も、めっちゃいいってわけではなく落ちこぼれない程度のものだ。そんな僕が、今回学生枠とは言え、全国で一位のチームに名を連ねる事ができたことが、本当に衝撃的だった。一生無理だと思っていた。もう自分でも何書いてるのか分からなくなって来てるけど、とんでもない喜びだったことを察してほしい。(でも社会人枠の人たち倒さないと本当の一位とは言えないよなーってちょっと思ってる・・・無理・・・)。

 

次もがんばるぞ!