こんにちは。 pixivの投稿ユーザ向けグロースを担当しているエンジニアのsestaです。
4月28日、ISUCON6本戦の問題を作ったedvakf、catatsuyと一緒に第2回社内ISUCONを開催しました! ISUCONとは3人までのチームで参加し、与えられたウェブアプリケーションのチューニングを制限時間いっぱい行い、パフォーマンスに基づいたスコアで競いあうコンテストです。 去年の社内ISUCON開催記事に引き続き、 今年は当日の様子のレポートとベンチマークなどの全体構成について紹介します。
当日の様子
今年は38人もの社員が参加し、その中にはなんと、ビジネス職の新卒や人事(!?)も参加していました。 競技時間は10:30から18:00までと本番のISUCONと同様にしました。
10:30によーいどんで始めた社内ISUCONですが、前半はなかなかスコアを伸ばすチームが現れませんでした。 CTOから煽りが入ります。
そんな状況の中、スコアを伸ばしてきたチームが現れます。 まさかの新卒エンジニアのabcangとnonoです。学生時代にISUCON本戦に出てただけあります。
この後、先輩エンジニアも負けじとどんどんスコアを上げてきます。 いい感じの混戦です。
そして終了時間の18:00になりました。
最終的にもっとも点数が高かったのは、リードエンジニアであるatsumuでした! atsumuは参加予定ではなかったのですが、社内のエンジニアが楽しそうにやっている様子を見て我慢できずに駆けつけました。
1人で優勝してしまうあたり、貫禄のリードエンジニアですね。
直前まで別のチームが1位でしたが、最後のどんでん返しによる盛り上がりはさすがISUCONといった感じでした。
競技の問題と構成
今年の問題はISUCON6本戦とおなじもの(https://github.com/isucon/isucon6-final)を使用しました。 ただ、そのままだとISUCON本戦の時と全く同じ改善をすれば優勝できてしまうため、ベンチマークの内容を修正してシステムのボトルネックを変えて使用しています。ベンチマークを修正したリポジトリが以下になります。
https://github.com/sesta/isucon6-final
ISUCONをやるなら競技用のインスタンスとは別にベンチマーカーと結果の集計を表示するポータルサイトが必要です。 今回はそれぞれ以下のように用意しました。
- 競技用インスタンス: Amazon EC2(t2.medium)
- ベンチマーカー: Amazon Lambda
- ポータルサイト: Mackerel
EC2は作成できるインスタンス数の上限が、t2.mediumだと20と決まっています。
今年も上限を超えそうでしたので、事前に申請フォームから申請を送り、上限を上げていただきました。 今年も対応いただいた、Amazon Web Servicesさんありがとうございます。
去年の社内ISUCONやISUCON6本戦のベンチマーカーは、どちらも自前でジョブキューの仕組みを持っています。 そのためジョブキュー自体とジョブキューを実行する複数台のサーバーのクラスタ管理が必要ですが、社内ISUCONでそこまでコストをかけるのは少し辛いところです。 さらに、ISUCONは後半になったら多くのチームが駆け込みでベンチマークを始めますので、サーバーの台数を増やすといった作業も必要になります。 そこでカヤックさんの社内ISUCONの記事を参考に、Amazon Lambdaを採用しました。 Lambdaはリクエストに応じてジョブキューのスケールアウトを自動でやってくれますし、何よりサーバを立てる必要もありません。
Lambdaを利用することでジョブキュー全般の管理から解放されたため、あとはベンチマーカーの結果をグラフで表示するだけです。 ベンチマーカーはサーバーレスにしましたし、折角なので全てサーバーレスにしてしまおうということでグラフの表示もMackerelにしました。
また、チームの情報はGoogleスプレッドシートで管理して、こちらの記事を参考にJSON API形式で取得できるようにしました。 ただし、記事に書かれているようにリダイレクトを考慮する必要があります。 今回はJavaScriptを使ってLambda側の実装を行ったので、HTTPクライアントとしてrequest/requestを使いました。 これによりチーム名やインスタンスのIPアドレスといった情報をLambdaから参照することができ、atsumuのように途中で参加者が増えることになっても簡単に対応できました。
構成をまとめると以下のようになります。
競技用インスタンスのEC2とLambdaはAPI Gatewayでつなぎ、インスタンスからAPI GatewayのURLをcurlで叩けばベンチマークが走るようになっています。 また、ベンチマークのスコアや失敗した時のメッセージをレスポンスに含めることで、curlの出力でこれらの情報を確認できるようにしました。
ベンチマーカーをLambdaにするために
とても便利なLambdaですが、利用する際に注意しないといけない点がいくつかあります。 それはタイムアウトの時間です。Lambda自体はタイムアウトの時間を300秒まで伸ばすことが可能です。 しかし、各競技インスタンスとLambdaの間に入るAPI Gatewayは 30秒でタイムアウト(2017年5月時点)になってしまうのです。 ISUCON6本戦のベンチマークは60秒リクエストを送り続けるものでしたので、そのままだと504が返ってしまってベンチマークが成功したかどうかわからない状態になってしまいました。 結局、この問題はベンチマークの時間を20秒にすることで対応しました。
今回の構成ではポータルサイトからベンチマークを開始させるのではなく、各インスタンスからcurlでAPI GatewayのURLを叩くとベンチマークが走るようになっています。 そうなるとLambdaからリモートIPアドレスを把握できるため、Googleスプレッドシートのチームの情報をAPIで取得できれば、どのチームがベンチマークを走らせようとしているかわかります。
あと、Mackerelのグラフに表示するためのmetricNameは英数字やアンダーバーなど特定の文字しか 許可されていないことにも注意です。チーム名を日本語にすることはできません。また、ログインしないとグラフを見ることはできないため、参加者などグラフを見たい人にはアナウンスしておく必要があります。
これらの工夫をまとめたものが以下のソースコードです。URLやキーは消してますが、ほぼそのまま使ってます。
https://gist.github.com/sesta/eb0404ba68c7eb1782732c0094517000
このコードのデプロイはLambdaの環境を簡単に構築できるServerlessを使いました。簡単にデプロイできていい感じでした。
準備の段階ではいくつか躓いてしまったLambdaですが、いざ本番になってみると何も問題なくベンチマークを実行してくれました。
振り返り
普段とは違うフレームワークや構成に触れることができるISUCONは、エンジニアにとっていい刺激になります。 終わった後の勉強会では、dockerについてもっと知りたいと手を上げたエンジニアが増えました。 新卒エンジニアもリードエンジニアも関係なく、どのような改善をしたかを聞きあっている姿はISUCONだからこそです。 まるで、テストが終わった放課後の教室にいるような、懐かしい空気が流れていました。
ピクシブでは4月に中途5名と17名の新卒、合計22名が新しい仲間として加わり、社員数は150名を超えました。 プロジェクトの数が増えたりビルのフロアが2Fと6Fに分かれたりと、どうしても他のプロジェクトのエンジニアと顔を合わせることが少なくなってしまいました。 そのような状況の中で、社内ISUCONを通してプロジェクト関係なく多くの技術職、ビジネス職の社員がシステムの高速化という1つの目標に向かう一体感は最高でした。来年もやりたいですね。
なお、本家のISUCONは今年も開催されるとのことです!ぜひ参加をご検討ください!
エンジニアを募集中です。
ピクシブ株式会社ではISUCONに興味があったり、システムの高速化が大好きなエンジニア大募集中です!