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

ISUCON本戦で人権を失った

予選突破の喜びはこちらです.

programmermot.hatenablog.com

結果

覚えてないけど初期実装下回る点数がでたので人権がない.さすがにつらすぎて記録とるの忘れてた...

当日の様子

f:id:programmerMOT:20161022204227j:plainf:id:programmerMOT:20161022090836j:plain

チーム卒業の軌跡

時系列はちょっと怪しい.

まず問題を確認.

ISUCON6本選オープニングプレゼン #isucon /isucon6-final // Speaker Deck

Docker,Reactで後ろにWebappがある感じ.Server Sent Eventが何か知らなかったけどとにかくPushする機構というのを理解した. 最初の1時間をかけてコードを読んでだいたい構成がわかったからどのようにスケールさせるかを考えた. 最初から5台使うことを考えて,

  • nginx + react(1台)
  • app (2台はapi,1台はstream)
  • mysql(1台)

という構成にすることになった*1

ここで何をトチ狂ったかh2oを試そうとして1時間を潰した.落ちついてnginxにして,各マシンにプロキシするようにしてエラーが出ないようにした段階で既に半分時間が過ぎている形となってしまった. こっからかなり焦ってしまって小手先のコード変更ばかりしていて,コード変更→Fail→なんとか治す→Successしたけど点数減る→変更→Failみたいなループを始めてもうダメだこれうーんどうすればいいんだと思ったところで8時間が終わってしまった.

abcangくんにはapp(ruby)周りの高速化をお願いしていた,がそもそもそれ以外の最適化がちゃんとできていなかったので旨味を感じる前に終わったのかなぁと思っている. syusuiくんにはmysql周りのセットアップとappの/api/streamまわりをお願いしていた,がそもそもそれ以外の最適化がちゃんとできていなかったので旨味を感じる前に終わったのかなぁと思っている.

つまるところ,どうでもいいことに対して時間を使い適切な指示が行えなかった僕に大きな失敗だった感がある.

やるべきだった点

  • Reactのproxyやめるのが遅かったもっと早い段階でできた
  • Reactさーばを分散させること.ここを一台で回すのどうやら失敗っぽい

良かった点

  • 朝起きれた

良くなかった点

  • あんまり使ったことのないh2oを利用したこと.使ったことのないものは結局使えないというISUCONの原則に反していたのは大きい失敗
  • 最初っから5台使い切ろうみたいな戦略にしたこと.もっとスモールスタートでも良かった気がするし,5台使わなくても十分学生top取れたと思う
  • Reactが大きなボトルネックになることを見抜けなかったこと.Reactは全員あんまり理解していなくて手を出さなかったのが完全に良くなかったと思う
  • ちゃんとした計測をしなかったこと.推測するな計測せよの原則に反していたのは大きい失敗
  • サーバ整うのに時間がかかってアプリの最適化着手が遅くなったこと.これは本当に申し訳なかった

まとめ

こうしてみると,ReactとかDockerとか使ったことはあるけどチュートリアル試したりちょっと使う程度でしか使ってなかったものがあったせいでびびったというか怖気づいてしまったのが大きいのかなと思う.あとそれに焦ってしまって適切な計測をせずに手を動かしたのは良くなかった.ちゃんとできることを確実にしているだけでも良い点数が出たと思うし,上位にも食い込めたとは思う.今回特に辛いのは参考実装を下回ったという事実でこれが本当に辛い.

今年はReactとDockerが現れたのはかなりびっくりしました.

今後に向けて

チーム卒業は今年度卒業して来年から社会人になる人間たちで構成された学生チームでした.我々は学生チームということで今回はかなりチャンスだったのですが,それを逸したことは悲しいです. ただ得るものはすごく多くて,もう既に出ている上位チームの解法であるとか,講評などは非常に勉強になっています.我々もここで折れずに来年はチーム新卒としてISUCON7に参加したいと思います.

メンバーの声

abcangくんの感想です

abcang.hatenablog.com

syusui!!!!!!!!!

改めまして,運営出題者のみなさま,会場提供を始めとしたスポンサー企業のみなさま本当にありがとうございました.ISUCON7期待しています. これはそういえばなんですけど,2015年の夏にあったISUCON夏期講習で勉強になったことが今回かなり生きたのでLINEのみなさま後輩たちのためにも続けてほしいです.

インターネットの様子

悔しい

*1:思えばここが失敗だった

ひげそり

ヒゲ.T字カミソリを使って風呂の際に剃ってるんだけど,今朝シャワー浴びたときに刃がだめになってきたから捨てたのでカミソリない状態だった.

捨てたは良いが新しいインスタンスを用意していなかったので,父親がどこからかパチってきた旅館とかに置いてある感じのカミソリで剃ったところすごい勢いで顎も剃れて血が出てきて大変だった*1.もう少しちゃんとしたカミソリ買ったほうが良いということを認識した.帰りにでも買う.

*1:そんなすごい剃れたわけじゃないけど

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宅で焼きました。

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

焼いている様子です。

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