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

ISUCON6予選に学生枠で参加して予選通過した

予選通過した!!!!!!めっちゃ嬉しい!!!!!!

isucon.net

結果

チーム名: チーム卒業

学生枠4位 42979点

メンバーと役割分担

  • @pg_mot : インフラ周り
  • @ABCanG1015 : ミドルウェアとアプリ
  • @syusui_s : アプリ

役割分担と書きましたが,実際には高度の柔軟性を維持しつつ臨機応変に役割が変動していった感じです.

準備

チーム結成後はslackチームを作り,githubsshキーとかリポジトリを作成して共有したりしました. あとは, HackMD - Collaborative markdown notes Hackmdっていうマークダウンで書けるGoogle Docsみたいなやつを使って資料やログ,作業ログの共有をしました.

参加前に何度か練習をしておきたいと思って, ansible-isucon/isucon5-qualifier at master · matsuu/ansible-isucon · GitHub こちらのイメージを無料課金枠で置いておいて各自好きなように変えようみたいな仕組みにしました.

本当は8時間とってやりたかったけど,時間がなくて個人練習を個別にやっておこうみたいな雑なノリで当日を迎えました.

当日の流れ

開始前

まず,始まる前に作戦会議をして,最初にやることリストを挙げたりしました. 具体的には,ssh-keyの登録だの,ベンチとりあえず回すなど先人の知識を元にホワイトボードに書き出して役割分担しました.

開始後

とりあえずazure deployしてその間にレギュレーションやマニュアルの読みあわせを行いました. deploy後はソースを全員で読んで挙動確認をしたりしながら,ベンチマーク回し始めました.

ちなみに今回はRubyを選択しています.

詳しい課題内容はそのうち公開されるので詳しくは書きませんが,要するにはてなキーワード自動リンク + はてなスターを高速化するという感じです. この自動リンクは非常に面倒で,初期実装では存在するキーワードを全部「|」パーティクルバーでつなげて正規表現をかけて,該当したワードのところをaタグに置き換え直すという処理が行われていました.この実装だと,キーワードの数に比例して計算量が増えていく上,ページレンダリングの際に毎回処理していたりすると大変なことになるのがわかります.

この時点で,プロファイラなどを取ったところ80〜90%が使われていた上,他にボトルネックになっていそうなところがパッと見でわからなかったので,何らかのアルゴリズム置き換えが必要だと考えました.キャッシュ戦略も取れるかなと思ったのですが,キーワード追加の際には結局再度キャッシュ生成が必要なので,対して効果がなさそうと判断しました.

とりあえず「はてなキーワード 実装 高速化」などで調べると, エイホ–コラシック法 - Wikipedia このようなアルゴリズムについての説明が出てきました.

当初はこの実装は間に合わない可能性が高く,手を付けない方針でしたが,逆にそれ以外のボトルネックを見つけるのが難しかったのと,syusuiくんのruby力を見込んでお願いしたところやる気になってくれたのもあり,AC法の実装を決断しました.

並行して,僕とabcangくんは他のボトルネック探しと,解消をはじめました.

ベンチマークを何度か回しているうちに,自動リンク機能以外のところでタイムアウトが大量発生していることに気づきました. 最初はnginxやsysctlのパラメータなどを先人のタレを使い設定してみたりしましたが,どうも解消せず少し時間を食ってしまいました.

昼を過ぎ間もなく時間も折り返しという時刻近くになり,はてなスターの処理がどうもミスを繰り返していることに気づいたので実装を見返すと,はてなキーワードはてなスター間のスター情報のやり取りにHTTPが利用されている!ことに思い出し(microserviceみたいになってた),冷静に考えると,「ベンチマークがHTTPでめっちゃやってくる」→「スター情報のやり取りで自分にHTTP投げる」→「ソケットやら負荷やらが集中しスター情報のやり取り及びベンチマークのHTTPが処理できなくなる」→「結果的にベンチマークタイムアウトが発生する」という流れになっていることがわかりました.

ここで,はてなスターの処理をすべてはてなキーワード側に移植したところ,1000点以下ではありましたが,点数が出始めました. 今になって思えば,ここは正直もう少し早めにやっておくべきだったかなと思います.当時は自動リンク機能が重いからそれ直さないと時間かける意味があるのかわからないというあたりで放置していました.

タイムアウト問題が大方直ってきたあたりで,abcangくんには自動リンク機能のリンク作成時に利用するkeywordリストを生成するSQLが重い問題についてredisを利用しての解決に着手してもらい始めました.僕はこの間に他の問題点を探して細かく潰したり,時間管理をしつつ二人をフォローする形に回ることとなりました.

そうこうしているうちに,syusuiくんによるAC法実装が完成しアプリに組み込む流れとなりました.アプリに組み込みベンチマークを回すと,1万点ほどまで点数があがりました. またすぐに,abcangくんのredis実装周りが終了し互いを組み合わせると一気に3万か4万点まで上昇しました.参加は2日目だったのですが,リーダーボードに我々のチーム名が乗っていたのは非常に感動しました.

f:id:programmerMOT:20160919153514p:plain

他にも施策としてstatic fileをnginxから配ったり,select *をやめたりと細かいことをしました.

その後,再起動後に正常に動くかという検証・修正や,AC法を中心とした全体の細かいエラー潰しを行い無事今回の点数が出ました. 最後の方は時間がぎりぎりになり終了10分前にようやくPCから手を離すというかなりギリギリのラインを攻めてだいぶ疲れました.

まとめ

良かった点

  • syusuiくんがAC法実装しっかりやってくれたので助かった
  • abcangくんがredisとかの実装しっかりやってくれたので助かった
  • 自動リンク機能から逃げなくてよかった(逃げなかったsyusui君偉い)

良くなかった点

  • starの処理統合をもっと早い段階ですればよかった
  • 自動リンク機能以外のボトルネック探しが遅かった
  • 最後の方もう,いてまえいてまえの精神でガンガン設定変えたりしてしまった(結果論的によかったけど本番は気をつける)
  • isupamについて何もしなかったのはアレでよかったのかな?

感想

勉強になればそれでいいか〜ノリで行くぞみたいな気持ちであんまり練習できてなかったにも関わらず学生枠という形で本戦参加できたのはすごい嬉しいです. 本番でも自分たちの全力を出せるように腰を入れて練習していきたいと思いました.

また今回の予選を準備し提供してくださった運営の皆様,大変お疲れ様でした.本戦でもよろしくお願いいたします.

関連ポスト

チームメンバーのABCanG1015くんの記事 abcang.hatenablog.com

ここにsyusui_sくんの記事リンクが貼られます.

9/8

rubykaigi1日目でした.

rubykaigi自体は初めての参加で,全体的に英語が使われるイベントな印象を持ちました. 僕は英語力が皆無でスライドのソースコードでなんとか切り抜けるみたいな人なんですけど,まあ大変でした.

ノベルティいっぱいもらったし,会場は綺麗だし,電源あるし,お弁当は美味しいので良いです.

明日も行きます...が,朝9:30からっぽくて正直異常に早い気がしていて,昼手前ぐらいから行くかもって感じです.

9/5

大学行ってゼミした。ゼミは不穏なこともなく無事に終了した。

最近Reactを研究の使うツールのフロントエンドとして書いていて、よくわからんけど書いてるみたいな感じ。

最初一つのReact.Componentのrenderにいろいろ詰めまくったせいで大変なことになっていて、今リファクタリングしてる。 内部はstateでめっちゃいい感じに共有してたせいで、書き直しが大変。最初っからちゃんと書けばよかった。

今週kaigiとかあるのでもう大学に行かないと思う。

9/3

朝から@PG_nokkii宅で焼きました。

集まったあと某所にあるコストコっぽい感じのでかいスーパーに行きました。とにかくビッグ。写真はない。

焼いている様子です。

火をおこすのに頑張って団扇を扇いでいたら、灰が飛んでビールに入ってしまった。灰はおいしくないけど、アルコール消毒されているようなものなので問題ないという理論で乗り切った。

9/1

9/2の記事は数時間後に書かれます.お楽しみに.

中間発表という地獄を抜けたので,同期と酒を飲みに行こうと計画して移動はじめたら二日酔いが大変などと供述しはじめて,延期になった. とはいえ体は完全に酒のスイッチが入っていたので,仕方がないから酒を飲みに行った.

その時の写真は撮りそこねたので,別の日に親の金で行った居酒屋の様子の写真で締めとしたいと思います.

延期になった祝杯の会は本日2時間後に行われます.