エンジニア向けの競技コンテストの1つであるISUCON11に参加することになったので、コンテストの予選に向けて傾向と対策を技術ブログの記事としてまとめてみました。
エンジニア向けの競技コンテストの1つであるISUCON11に参加することになったので、コンテストの予選に向けて傾向と対策を技術ブログの記事としてまとめてみました。
みなさんこんにちは!どんなに暑くても熱いお茶とコーヒーが大好きな株式会社EMoshU・CTOの松村です。(8月に書いてます)
今回はエンジニア向けの競技コンテストの1つであるISUCON11予選に参加することになったので、コンテストの予選に向けて傾向と対策を技術ブログの記事としてまとめてみました。
ISUCONは、LINE株式会社が運営するコンテストで「いい感じにスピードアップコンテスト」(Iikanjini Speed Up Contest)を略してISUCONと呼ばれています。(面白いネーミング)
何をいい感じにスピードアップするかについてですが、コンテストではお題として与えられたWebアプリケーションを時間内に高速化し、そのスコアを競う競技となっています。
我々がISUCONに取り組む意義としては、まず社の方針として多くの人に使ってもらえるサービスを世に出していきたいという気持ちがあります。その上で、ユーザーやサービス規模が大きくなっていった際に、使い勝手が悪くなってしまってはサービスをグロースさせることができません。そのため、サービスのボトルネックを見つけ改善していくノウハウを、このようなコンテストを通して体得していきたいという思いがあり、参加することにしました。
ちなみにチームメンバーとして、頼れるエンジニアマネージャーまさきもいっしょに参加します。
ISUCONは今年(2021年)で11回目となり昨年の10回目から参加者数が大きく増えており、年々注目度が増しているように思われます。本当は昨年のISUCON10も参加したかったのですが、すぐに参加枠が埋まってしまい参加することができませんでした。
このコンテストは、最大3名を1チームとして8時間という制限時間内に出題されたお題のボトルネックを見つけ出し改善していく必要があります。当然何も準備せずに挑戦しても何もできないまま終わってしまいますので、しっかり過去のお題を分析しておく必要があります。
そこでこの記事では、ISUCONに参加するにあたっての対策や問題への対応方法を紹介していこうと思います。
まずはレギューレション(規則)を確認しましょう。
競技コンテストですので決められたルールに従わないといけません。レギュレーションには使用できる言語や提供されるサーバの環境、採点方法などの基本的な情報の他に何をやっていいかという高速化をする上で重要な事柄も書かれていたりしますのでしっかり確認しておきましょう。
問題の実装で使われている言語はGo, Node.js, Perl, PHP, Python, Ruby, Rustになり(ISUCON10予選レギュレーションより)、どれを選ぶかについては慣れている言語が一番良いのではないかと思います。私を含め弊社のエンジニアはPHP経験のある人が多いのでPHPでいくことも考えましたが、次の自社サービスではGoを使って実装したいと考えているのでGoで挑戦する予定です。実際の参加者の利用比率だとGoを選択するチームが多いようです。
ISUCON10 予選レギュレーション : ISUCON公式Blog
予選参加者(以下選手)はチームで登録するものとし、チームは1名、2名、もしくは3名での登録とする。チームは「一般枠」「学生枠」のいずれかに登録される。予選へ参加するチームの合計は 500 を超えないものとし、参加登録は先着順とする。本選参加チームは 30 チームとし、予選の競技結果から選出される。
ISUCON10 オンライン予選の利用言語比率 : ISUCON公式Blog
ISUCON10 オンライン予選の利用言語比率を公開します。オンライン予選は490チームの参加があり、運営で把握ができたのは468チームとなりました。利用率の全体ランキングは以下の通りです。
内容を確認した後にやるべきこととしては、やはり実際出された過去のお題を解いてみるというのが一番良い
でしょう。過去のお題は予選・本戦ともに公式のHPから辿ることができます。環境の構築方法も公開されているので、実際にローカルPCで動作確認ができる問題をやってみると良いでしょう。
私はISUCON10予選とISUCON9本戦をローカルPC(MacBook)で動かして確かめることができました。問題によっては環境構築でつまずく可能性が十分あり得るので、公式の「過去問にチャレンジするためのシンプルな環境構築」(下記リンク)を参考にして動かしてみるのが良いかと思います。
ISUCONの過去問にチャレンジするためのシンプルな環境構築 : ISUCON公式Blog
過去のISUCONで出題された問題をシンプルに環境構築できるページなどを紹介します。 ・AWS環境で構築する。・Docker環境があればすぐに構築できる。・VagrantとVirtualBoxがあれば構築できる。・WSL2があれば構築できる。・ConoHaのVPSで構築する。・VirtualBoxがあればすぐに構築できる
それでは、次からは問題を解いていく上でのボトルネックの探し方をみていきたいと思います。
動作確認ができたら、次にやるべきことは情報の収集です。改善しようにも何がボトルネックになっているかが分からなければ対応しようがないからです。
それではどこから情報を集めてくるかですが、一番重要な情報が詰まっているのがアクセスログになります。アクセスログにはどこからアクセスされたのか、どこにアクセスしたのか、レスポンスを返すまでにどれくらいの時間を要したのかなどの情報が書かれています。
そしてこのアクセスログを集計してみると、どこへのアクセスに時間がかかっているのかが分かるため、ボトルネックとなっている箇所が一目瞭然となります。注意点として過去問などでDockerを利用する際はアクセスログの出力先が標準出力になっているので、ログをファイルに出力するように設定する必要があります。
アクセスログをファイル出力できるようになったら、実際にログを集計して分析します。ログ集計ツールとしてalpがよく使われているようで、実際に使ってみましたが簡単にインストールでき、集計も手軽にできて良い感じでした。下記にISUCONでのalpの使い方を説明したリンクを置いておきます。
主にISUCONで使われているアクセスログ集計ツール alp の使い方を、ISUCON10オンライン予選問題のアクセスログを例に紹介します。執筆時現在の最新バージョンはv1.0.7です。
以上がアクセスログについての情報収集でしたが、さらにボトルネックを分析する上で重要な指標としてDBのスロークエリログ(slow query log)があります。文字通り遅いクエリのログです。サービスのリリース初期などDBのデータ量が少ない間はあまり問題になりにくいですが、ユーザー数増加に伴いDBに保存されるデータが増えてくると大きなボトルネックになってきます。そのため、お題のアプリケーションを動かしながらスロークエリログが出ていないか確認しましょう。スロークエリログはMySQLであれば、my.confファイルで検出するスロークエリの定義やログの出力先を設定できます。もしくは pt-query-digest のようなツールを使うのもの良いかもしれません。詳しくは下記を参考にしてください。
第131回 mysqldumpslowを使ってスロークエリログを解析してみる:MySQL道普請便り|gihyo.jp … 技術評論社
今回は,mysqldumpslowという,スロークエリログをもっと便利にするコマンドラインツールについて紹介していきます。
pt-query-digest - Analyze MySQL queries from logs, processlist, and tcpdump.
ボトルネックとなっているAPIやDBのクエリを見つけたら、次はそのボトルネックの改善をしてきましょう。過去問をやっていて一番スコアを改善できたなぁと思ったのが、スロークエリの改善です。遅いクエリを見つけたら、EXPLAIN などを使用して実行計画を確認してみましょう。大体、インデックスが貼られておらずフルスキャンによって重くなっていたりするので適切なインデックスを貼って対応します。
スロークエリを片付けたら次は遅いAPIの実装を確認して、ボトルネックとなっている箇所を探してみましょう。ボトルネックを見つける上で大事な観点としてはN+1問題がないかという点です。N+1問題とはDBからある情報のリスト(N個)を引っ張ってくる際にまず1回クエリを発行しますが、さらにそのN個それぞれのデータに紐づく情報をDBから引っ張ってこようとした際に、N回のクエリが呼ばれる実装になっている箇所です。合計N+1回のクエリが発行されるため、Nの数が大きくなるとパフォーマンスが落ちてしまいます。実装上は1回クエリを発行した後、その結果を使ってfor文を回し、その中でクエリを発行する実装になっている箇所が該当します。このような箇所を見つけたら、1回のクエリで結果を取得できないか検討してみると良いです。
N+1問題を簡単に説明すると、クエリがデータ数よりも多くなります。データ数よりも多くのクエリが発行されることで、サービスのパフォーマンスを低下させます。少量のデータの場合は、問題を感じることは少ないと思いますが、実際にサービス運用では膨大なデータ量を扱うことがほとんどなので放っておくことはできません。
これまで説明した内容は基本的な改善方法になりますが、さらなるスコアUPを図るには与えられた環境やスコア計算時の特殊な要件を利用することも必要です。
例えば、コンテストでは複数台のサーバが割り当てられたりするのですが、重い処理がアプリケーション側にある場合はアプリケーションサーバに多くのサーバを割り当てて改善するという方法があります。また、問題によっては外部APIと通信している箇所をバックグラウンドで処理してもよかったり、botからのアクセスは503を返すようにしても大丈夫などの特殊な要件も書かれていたりするので、その辺りを見逃さずに対応することもスコアUPには必要になります。他には表示レスポンスの改善にキャッシュなどを利用するというのもありそうです。
最後に、コンテストは作業できる時間が限られているので時間を有効に使うことが重要になります。そのために前準備をしっかりしておくことも大事になります。問題は異なっても最初にやるべきことは計測になります。その計測を素早く行うためにもツール類は事前に準備しておきましょう。
また、複数名のチームでチャレンジする場合はそれぞれが対応する領域(アプリケーションやインフラなど)を決めておいたり、お題のソースコードをgitで管理してissueベースで改善していくなどチームとしての方針も重要になりそうです。
ISUCONの最初の30分にやること[計測編] - 心の声を垂れ流す場所
今日はバ先の人と3人で ISHOCON1をやりました。 今回はチームではやらずに各個人で黙々とやりましたが、僕以外はisuconやるのも初めてという事でかなり苦戦していた様子でした。(僕も無事に死にましたが、、、) ISUCONの最初の30分で秘伝のタレを入れたり、使い慣れた計測ツールを入れたりするのは定石となっていますが、初めてやる方はそこで詰まるというのもあるかと思いました。 計測してしまえばあとは取り除くだけ!という事で、最初の30分 ~ 1時間でやりたい計測ツール導入をドキュメント化しようと思います。 (推測するな。計測しろ!という名言は私の言葉です)
今回の記事では、ISUCON予選に向けた対策と問題への対応方法について説明しました。まとめると以下のような感じです。
今回記事としてまとめた内容はISUCONに参加する上で最低限知っておくべきことを中心に書いてみました。予選を突破するには紹介した内容以上のことが求められそうなのでなかなかハードルが高そうですが、できる限りのことをやってみようと思います。また来年以降も継続的に参加し、他のエンジニアさんと切磋琢磨できたらなと思っています。
この記事をみてISUCONに興味を持たれましたら、ISUCONのホームページを見てみることをおすすめします。ホームページには過去問やその解説もありますし、座学の動画も配信されているので、興味のある方はぜひご覧になってください。
お題となるWebサービスを決められたレギュレーションの中で限界まで高速化を図るチューニングバトル、それがISUCONです。
ISUCON 事前講習2021 座学 を開催しました(資料と動画と問題あり) : ISUCON公式Blog
ISUCONについての理解、問題の解き方について深く学ぶことができるオンラインイベント「ISUCON 事前講習 2021 座学」を開催しました。カジュアルに質問を受け付け、参加したことがないという方にも好評をいただきました、ぜひアーカイブをご視聴ください。 当日は、ISUCON9
最後に、EMoshUではメンバー一丸となってより良いサービスを世に出すために頑張っています。そんな中で一緒に働きたいという方がいらっしゃいましたら是非ホームページからお問い合わせいただければと思います。そして一緒にISUCONのようなコンテストにも参加しましょう!