でこてっくろぐ ねお

UbieのSRE。でこらいふろぐ(http://dekolife.hatenablog.com/)の姉妹版。デコテックログ(deko tech log)である

PHP使いとScala使いとPerl使いが集まって #ISUCON 予選敗北した話と雑な決勝内容予想

タイトルの通りで、PHP使いとScala使いとPerl使いが集まって死力を尽くしたのですがISUCONに敗北したのでした。ISUCON当日までの流れと当日の反省点などを記録していきたいと思います。特に技術的内容はない。

 

ついでに、最後に雑な決勝の予想を載せておきました。

 

ブログ書かねばと言いながら延び延びになっていていつのまにかISUCON決勝が明日に迫っていたので慌てて公開。


チームビルディング

かれこれ2年連続PHPでISUCONに出場し、2年連続で「優勝してPHPの優秀さを証明してみせる」と言っては決勝までは進むけれども決勝では惨敗する というのがいつものパターンだった私ですが、今年は夏に、はてなという名前のPHPのピの字もないPerlScalaの会社にインフラ担当として転職しておりまして、「はてなの社員とISUCONに出た場合、PerlScalaになるだろうしPHPの優秀さは示せそうにないのが極めて残念ではあるが、 それはそれとして今年こそ優勝するぞ」と強い意気込みをもって過ごしていたのでした。

そして優勝するために社内のいろいろな人に声をかけつつチームビルディングを行っていたのですがそこで誤算発生。なんと、ISUCON決勝のある10/31は私の大学時代の友人の結婚式の日でありまして、 皆がISUCON決勝を頑張っている中、私ははるか遠く九州まで出掛けていることが発覚したのでした。

流石に決勝に参加できないのは申し訳ないということで当時声をかけていたメンバーには一度チーム解散宣言をしたうえで、「決勝には出られないのですがISUCON予選だけでも出たいです。 誰か一緒に参加していただけませんか」と弱気に社内で呼びかけていたところ、超若手が参加してくれることになりました。彼は社内でScalaを書いており ました。私はPHP使いながらもScalaJVMは学ばなくてはいけないと思っていたので、「よしScalaで予選を戦おう」と決めたのは大変自然な流 れだったのでした。そして、更に「Scalaで戦うのですがScala使いでもScalaを勉強したい人でも、あと1人メンバー募集中です。」と社内で声をかけたところ、若手のホープ新卒2人目、Perl使いが手を挙げてくれまして、無事にISUCON予選には3人チームで参加できることになったのでした。

このような流れで、PHP使いとScala使いとPerl使いが1同に会すというドリームメンバーでISUCONを戦うことになったのでした。

決勝に出られない私がチームを組めたというのは大変ありがたく、嬉しく思った次第で「(私は参加できないけど)若い2人に絶対に決勝を体験してもらいたい」と強く決意した次第でした。

なお、インフラ担当は私であとの2人はアプリケーションエンジニアとなっております。また、前々から「ISUCONで若者潰す」みたいなことを言っていたのですが、超若い2人とチームを組んだことにより平均年齢が劇的に下がったため方針を転換し「おっさん潰す」という感じで頑張ることにしました。

 

なお、1人は京都から参加で残り2人は東京から参加ということで、遠隔でやってました。


チーム名決め


チーム名は大切です。これによって当日のテンションがかなり変わってきます。


scala祭り」「常勝」「殺戮摂理(ラジカルサーカス)」「二重言語(ヒステリックリボルバー)」など色々案を出しましたが、結局参加者各位のIDを混ぜたようなチーム名に落ち着きました。


事前準備


Scalaで行く」と言ったもののインフラ担当の私がJVMの知識が全くないこともあり、必死でJVMの勉強を行いました。具体的には、社内でJVMのインフラを見ている方に「JVM勉強したいんですがいい本ないっすか」と聞いて教えてもらえた「Javaパフォーマンス」をひたすら読んでいました。その結果、JavaGCについては結構詳しくなった感じがしました。

 

O'Reilly Japan - Javaパフォーマンス



また、最初に設定したいカーネルパラメータの値や入れておきたいツールについてまとめたりをしていました。


当日開始前、再度の使用言語決め


私たちはISUCONの2日目に参加したのですが「Twitterを見ている限り、ISUCON1日目のPHP実装は何か変なことがあったっぽい」「ISUCON1日目はNode実装がなかったらしい」という情報を見て、「Web業界ではそこまでメジャーではないScala実装も何かしら問題がある可能性がある、最悪実装自体が存在しない可能性がある」という結論に達し、もしscalaがダメだった場合の使用言語の選定方法を決めることにしたのでした。

そこで再度3人の使用可能言語などを調査したところ、PHP, Scala, Perlの超得意言語の他にも「3人ともJSは書ける」「@stefafafanはPHPを読んだことがある」「goなら3人とも大丈夫?」などという話が出たのですが、結果として、「特に何事もなければScalaでいく」「もしScalaに何かあった場合は@stefafafanがまだ読め、私が超得意なPHPでいく」という結論になったのでした。

今思えばこれが失敗でした。インフラ担当の得意なPHPでそのままいくのではなく、アプリケーションエンジニアが得意な言語に合わせるべきで「ScalaがダメだったらPerlでいく」というのが正解だったなぁと今になっては思います。

 

当日、開始

 

開始して早々「Scala実装では初回のベンチマークは通りません」という話が出てきたため、Scalaはやめて上記決めていた方針通りPHPでいくことに決定しました。

 

アプリケーションエンジニア2人にはコードを読んでもらいつつ私はとにかくアプリケーションを動かすというのに注力しながら頑張っていき、一旦アプリケーションを動かして最初のベンチマークが通ったのでした。めでたかった。

 

当日、その後

 

アクセスログから遅いエンドポイントを特定し、スロークエリログから遅いクエリを特定し、というのを行いながら15時くらいに3位になってめっちゃテンション上がったりしながらも、得点の伸びがそこで止まり、その後は特に何もできず終わったのでした。

 

なお、my.cnfが別の場所にあることに気づかなかったインフラ担当の私は本当に死すべき存在として名前を刻まれるべきでしょう。

 

最後の10分くらいでなぜかベンチマークがfailし始めて、最終的に得点が出ませんでした。謎。

 

反省点

 

上にも記載したのですが、私がインフラ担当だったのに私が一番得意(他の2人はそんなに得意ではない)な言語を選択してしまったというのが最大の失敗で、前半の私のボトルネックっぷりが半端なくその結果様々な場面で問題が発生した感がありました。

 

私のせいで優秀な2人の足を引っ張ってしまったなぁと反省しきり。

 

私がボトルネックになったことで(というかむしろそれによって私がかなりテンパったことで優先度付けが崩壊し)最大にやばかったのが以下2点。

 

my.cnfが別の場所にあるのに気づかなかった

 

ISUCON開始直後、「my.cnfを書き換えてスロークエリログを出そう」となったわけですが、なぜかmy.cnfを書き換えてもログが出ません。あれあれおかしいなと思いながら、set globalでログを出すようになり、その直後に全然別の理由でmysqlが起動しなくなるなど事件がありそのままmy.cnfの件は忘れ去っていまし た。

最後の方で「あ、my.cnfの設定まだしてないじゃん」となりinnodb buffer poolの設定などをしたのですが「あれ、buffer pool増やしたのになんかOSがメモリ使ってないなぁ。DBデータのファイル量的にそんなことはないはずだが…なんかおかしいなぁ」と思いつつ、その後別の何かにまた忙殺されてそのままになっていたのでした。ひどかった…

 

各人の開発環境を作れなかった

 

毎年のように各人の開発環境をサーバ上に別ポートで立ち上げてそこで開発しようと思っていたのですが、どうもGCEでファイアウォール設定をしても動かない。ローカルの開発環境を作るのもPHPはちょっと面倒だなぁという感じで、最終的に、アプリエンジニアの1人はサーバ上のプログラムを直接編集し、もう1人はPHPを書いたことないにも関わらずローカルで適当に書き換えてはpushしてサーバ上で動作を見てみるという感じになり、かなりめちゃくちゃだった。

 

それにもかかわらずでかいパッチをポンと作ってそいつがほぼそのままパッと動かせることができた彼はスゲェなと思った限りでした。

 

良かったこと

 

とにかく、私が決勝に出られない状態にもかかわらずチームを結成できて予選に参加できたことは本当に嬉しかったです。また、同じチームだった若者2人はこの経験によって1年後、ものすごい人材になり来年の弊社の層は更に厚くなりいい感じだなという思い(若者に負けないようにもちろん私も頑張りますとも!)

 

あと、15時くらいにn+1問題解決して突如3位に躍り出たのは普通にテンション上がった。嬉しかった。

 

決勝予想

 

以下のようなナウい感じのワードが飛び交う

 

不必要なマイクロサービス

 

「マイクロサービス」などと言って1台のサーバ内に不必要に複数のdockerコンテナが(もしくは別ポートでHTTPサーバが何台も)立っておりそれぞれがお互いのAPIを叩きまくっている世界観。それらを分解する(マイクロサービスをやめるか、そのまま別サーバへ持っていくか)ところから全てが始まる。

 

ビッグ(?)データ

 

アクセス情報を貯めて最後にそのアクセス情報を集計させる。スループットが上がってベンチマーク中のアクセス数が増えるほど最後の集計でタイムアウトしやすくなる。

 

最初は同期的にログ書き込み及び集計をしているので、fluentd(等)を使って非同期にしたり集計を後でまとめてやるようにしたりすることで飛躍的に点数上昇が見込まれる(…のか…?)、等(出題陣から、やはりfluentdが活躍する何かが出てくるのではないかという予想がある)

 

最後に

 

来年こそは優勝したい(その頃にはPerlもしくはScalaの裏側に習熟しているように頑張ります)

 

というわけで、九州行ってきます!皆さんISUCON決勝頑張って!!!

 

併せて読みたい

 

t-kyt.hatenablog.com

 

stefafafan.hatenablog.com