ようやくやりたかった社内イベントであるRails ISUCONを開催できたので、そのことについて書いていく。
Rails ISUCONの目的
目的は、主に3つ。
- 自身の知見をチームメンバーに拡げる(チームメンバーから知見を得る)
- コミュニケーション
- 様々な角度からRailsアプリのパフォーマンス改善を学ぶ
うちのグループは全てRailsで作られた製品を扱っているので、Railsに特化したISUCONをやった方が効果があるし、製品へのフィードバックもしやすいという目論見がありました。
チーム構成
特に重視していたのは、1番目のチームメート同士での知見を交換することでした。そのため、1人チームや2人チームを作ることはやめました。1人だとコミュニケーションも生まれないし、知見の共有ができません。2人だと1人が一方的に作業をして、残された1人がただただ眺めてるようなことにもなりかねません。そこで、メンバーの技術力・コミュニケーション力のバランスを考えて、主催者側でチームとそのメンバーを決めて、3人の2チーム構成にしました。
アプリについて
Rails ISUCONなので、もちろんRailsで作っています。アプリは私一人で作りました。Railsでよくあるパフォーマンスが劣化しやすいポイントなどを最初に考え、それを盛り込みながらも、大きなアプリにならないようにと、画像投稿アプリを作りました。
パフォーマンスが低い要因
だいたいこんなところを仕込みました。
- 古いバージョンのRuby、ミドルウェア
- 適切なインデックスが設定されていない
- N+1問題を含んでいるActiveRecordのクエリ
- 何度も呼ばれるcount
- 必要だけど重いSQLで作られたView
- 最適化されていない画像サイズ
- Railsが全部のリクエストを捌いている
ベンチマーカーについて
ベンチマーカーを作る知見を全く持っていなかったので、当初は「Gatlingで適当にアクセスさせて、いくら捌けたかで得点にする」程度に考えていました(Gatlingの知見も持っていないにも関わらず😅)。しかし、他の業務も忙しくなったり、チームの育成に注力したりなどしていたため、なかなかベンチマーカー作成に着手できず、いよいよベンチマーカーなしでもとりあえず開催するか…という感じになってきていました。
isucandar(イスカンダル)の存在を知る
7月上旬に、fukabori.fmのISUCONの回を聞いて、ベンチマーカーフレームワークのisucandarの存在を知りました。これを使えば、知見のない自分でもベンチマーカー作れるかもしれない!と思い、とりあえず使ってみることに。ちなみにisucandarはGo言語で作られているのですが、この時点で私はGo言語を使ったことはありませんでした…😅
READMEを読んで、適当に作ってみていたら、Railsのログがバーッと流れ出したので、いけそうだなと思って、そのままやろうとしたのですが、Goでの関数化やメソッド化やエラー処理の仕方とかが全然わからなくて厳しくなってきたので、ここから急遽Go言語を学ぶことにしました。オリンピックの開会の連休を使って家にあった「プログラミング言語Go」を読んでました(本は買ってたけど読んでなかった)。
とりあえず家にあるGoの本を読もう。 pic.twitter.com/lRMGultMzj
— パトラッシュ@エキスパート職 (@patorash) 2021年7月21日
この本のときのGoのバージョンが1.6で、現在の最新バージョンが1.16なので随分と違いがあったりもしました。
文法や並行処理で気をつけることをなんとなく把握したところで、とりあえず関数化やメソッド化したり、作ってはリファクタリングしてを繰り返して、なんとか完成させました。その際には、本家ISUCONの10回目のベンチマーカーのコードを参考にさせてもらいました(正直まだ全然わからんところとか大量にあったけど)。
こちらのコードを読んで、isucandarのREADMEで書かれていなかったBenchmark, BenchmarkStep, BenchmarkResultなどの構造体の存在に気づき、それらを使うようにしました。ベンチマーカーをどう実装したかは、また別の記事で書こうと思います。
負荷試験のやり方を学ぶ
順番が前後しますが、負荷試験のやり方については、こちらのスライドで勉強させてもらいました。まずはlocalhostでうまくいくことが重要で、クラウドの場合は下手するとクラウドサービスに対する負荷試験になってしまいかねないので、それは避けるということがわかってよかったです。確かにやってしまいそう…。
これで学んだことで、とりあえずベンチマーカーはRailsが動いているサーバーに同梱してしまおうと考えました。Railsアプリとベンチマーカーがリソースを食い合うので、正確なベンチマークにはならないけれど、ネットワークの負荷をかけずに負荷試験できるので、これはこれでアリだと判断しました。
ルールなどのドキュメント
- ストーリー
- ルール
- 禁止事項
- ヒントになるようなことを他のチームに教えない等
- 各種操作方法
- Railsアプリケーションの起動方法
- ベンチマーカーの起動方法
などをWordで書いて、共有しました。チームのコミュニケーション方法は、MS Teamsのプライベートチャネルを作り、そこでやってもらうようにしました。当日はそのチャネルにパフォーマンス改善になりそうなブログのURLなどが貼られたりしてました。
社内ISUCON開催!
当日
8/6(金) 10:00〜18:00の8時間で取り組んでもらいました。 こちらの準備不足や考慮漏れもあって、多少ゴタゴタしてしまったりもありました(申し訳ない…😢)
ベンチマーカーのスコアを、どちらのチームも見られるTeamsのチャネルに投稿してもらったりして、結構盛り上がったんじゃないかと思います。終わった後は皆、かなり疲れてたようでした(わかる)
初期状態で2800程度のスコアが、最終的にはどちらのチームも7000以上になっていました👏
翌日
8/7(土)の朝だけちょっと皆に時間をとってもらい、1時間程度で振り返りを行ってもらい、その後、チーム毎に発表してもらいました。
- 何をやったか(それでどれくらい改善したか等)
- 時系列だとわかりやすいかも
- やろうと思っていたができなかったこと(時間が足りないと判断して後回しにしたとか)
- 感想
- イベント的に良かった点
- イベント的によくなかった点
- 等
チーム毎にどういうところに取り組んだかがわかって、面白かったです。また、イベントとしての反省点も見えてきました。インフラにあまり強くないと、改善用のローカル環境の構築自体がなかなか進まず、改善に取り組む前に時間がかかりすぎるとか…。まぁそれも含めてISUCONかなぁとは当初考えていたのだけれど、ちょっとこだわりすぎたかなと思ってしまいました。後で素振り用の環境は準備しようと考えていたので、そちらではすぐに取り組めるようにdocker-compose.ymlとかを同梱しようと思います。
あとは、想定していた改善点のポイントの残りなどで、こういうものが考えられるよっていうのを伝えました。無駄にでかくて最適化されていないトップ画像とかは、両チームとも全く気づいてませんでした😇プログラムだけ見ていたのではあかんのよ、リソースにも気を配らないといかんのよ…👻
どちらのチームからも上がった良かった点として、「ベンチマーカーのスコアが良くなるのが楽しかった」というのがあったので、やはりベンチマーカーを作っといたのはよかったです。
主催者としての感想
主催する側は相談するとネタバレになるので孤独で大変っていうのをfukabori.fmでも聴いてたんですが、それは本当にそうで、かなりシンドかったです。正直終わってかなり肩の荷が降りた気分です。でも問題を考えたり、ベンチマーカーを作ったりするのは楽しかったし、勉強にもなりました。当日のベンチマークスコアが良くなっていくのを眺めるのも、楽しかったです。
あとは皆が素振りできる環境を整えるというタスクが残っているのと、自分が思いつく全部の改善をした際のスコアを取っておくというのがあるので、休み明けも頑張ります👊
追記:isucandarの記事を書きました。