SREセクションの@morihaya55です。 9/12(Sat)に開催されたISUCON10(Iikanjini Speed Up CONtest)にチーム"おいら大地"で参加してきました。
ISUCON自体の解説は公式ブログにお任せするとして、10回目の今回は12:20-21:00の約8時間でIsuumoというWebサイトのサービスの速度改善を競いました。
私たちのチームの布陣は以下の3名で、なかなか良いバランスだったと思います。
- アプリケーション担当: @utautau16
- DB担当: @koyapig
- インフラ担当: @morihaya55
結果
チームとしてのスコアは以下の通り1,000に満たず、本線出場チーム(トップは7,000超え)との差に圧倒的な敗北感を味わうことができて最高でした。
- 開始: 231 (Pythonの初期値)
- 最終: 679
- 最高: 710
当日までの準備
出場する3名とも今回が初めてのISUCONのため入念な準備をするべきでしたが、実際に動き始めたのは1週間前程度からでした。 日中の30minで毎日集まりesaにやることなどをディスカッションしながらメモをしました。
事前準備の中でやったこととしてはざっと以下です。
- ISUCON 夏期講習 2020 の動画視聴と、スライドをみながらイメージを掴む
- レギュレーションを読み合わせ(文字通りローテしながら声に出して読んだ)
- 役割分担と最初の50minの動きを決める
- GitHubの用意&Slack連携
- 当日コミュニケーションの方法(基本Zoom繋ぎっぱなし&テキストはSlack)
- ISUCON9のリポジトリを眺める
- 使用言語をPythonと確定(全員が読めそう、という観点から)
- 当日の情報集積用esaページ作成
今からすると過去のISUCON環境を再現して素振りをするのも得点アップへは効果的だったと思いますが、当日の楽しい敗北感もまた良かったと感じています。*1
当日の振り返りと次へのコメント
以下からは当日の参加メンバがそれぞれの思いを自由に書きます。
アプリケーション担当: utautau16
morihaya55さんに誘っていただいて、初参加しましたが、
おもしろかったのと同時に自分の無力さをとても感じた8時間でした。
元々「ISUCON(Iikanjini Speed Up Contest)= いい感じにスピードアップコンテスト」を知らなかったのですが、
サイトを高速化するコンテストと聞き、おもしろそうだなと思って参加しました。
アプリケーションは、Go , Perl , PHP , Ruby , Node.js , Pythonで参考実装が与えられるのですが、
他の言語で、1から書き直してもよいというとても自由なルールでした。
ぼくたちのチームでは、メンバー全員がなじみのあるPythonで挑戦しました。
コンテストが開始し、メンバー間で当日レギュレーションを読み合わせ、
環境を整えたらすぐに、Pythonのコードを見ていたのですが、あまり高速化の案が浮かびませんでした。。
結果的には、/api/recommended_estateのクエリ内の処理を、
部分的にPython側でやらせることで、ORを減らしたり、条件文の書きかえを試行錯誤してみたり、
コネクションプール数をいじったりすることしかできず、効果的な改良をすることができませんでした。
New Relicでボトルネックとなっている箇所がわかっていたにもかかわらず、
それを改善する効果的な手を打てなかったのが心残りでした。
もっと日頃から、高速化するには、どうするかを意識していないとだめだなと、とても勉強になりました。
DB担当: koyapig
お恥ずかしながらISUCONの存在を知らず、@morihaya55 さんにお誘い頂きISUCON10参加してきました。
結果は気持ちがいいくらいの惨敗でした!
今回の惨敗によりDBの知識が低いと感じました。ただ、これはマイナスではなくプラスに考えており、もっと技術力を磨いたり知識を身に付けないといけないという刺激になりとても良い経験をさせて頂いたと思っています!
当日の振り返り
私はDB担当として参加させて頂きました。 当日何をやったのかというと、DBMSはMySQLを使用していたため、
- MySQLのバックアップ
- MySQLのパラメータの設定(MemoryやSlowQeryログ、QueryCacheの設定などなど)
- MySQLのIndex作成
です。
実際パフォーマンス改善につながったのは、スロークエリやNew Relicをみてインデックスを作成したことです。本来ならもっとDBだけでももっとチューニングの余地はあったと思うのですが、少ない作業時間で自分ができることを全力でやらせて頂きました。
次回について
次回も機会があれば参加したいです。もし次回参加するなら以下のことにチャレンジしたいと思っています。
- DBMSの変更
- DBサーバー分割
- パラメータチューニングによるパフォーマンス改善
また、今回はDB中心でみていたのですが、もっと余裕を持ってインフラ面やアプリ面も意見の出し合いがしたいと思います。
インフラ担当: morihaya55
「ISUCON初参加でしたが、こんなに面白いとは思ってませんでした!」
今回はオンライン開催と聞き、同僚と出たらおもしろそうだなぁくらいの軽いノリで申し込みましたがあの時の勢いに感謝しています。
当日の振り返り
インフラ担当として参戦して具体的には以下を行いました。
- New Relicの導入
- Netdataの導入
- Nginxチューニング
- メトリック/ログ監視
- OSチューニング
それぞれのざっくり概要を記載しておくと
New Relicの導入
New Relicは以下の順番に導入して行きました。
- New Relic Infrastructure
- New Relic Logs
- New Relic APM
- New Relic InfrastructureのMySQL Integration
InfrastructureとLogsはサクッと入れられましたが、APMとMySQL Integrationはてこずりました。
APMについては実行されるPython 3.8がローカルのbinにあることになかなか気づかずに、OSのPython 2.7を叩いていたことでバージョン不一致で動作しませんでした。(以下がその時のログで、この状態だとアプリは起動するがAPMのメトリクスは取られない)
+ /usr/local/bin/New Relic-admin run-program /home/isucon/local/python/bin/python app.py New Relic: 2020-09-12 06:06:56 (10103) - New Relic could not start because the New Relic-admin script was called from a Python installation that is different from the Python installation that is currently running. To fix this problem, call the New Relic-admin script from the Python installation that is currently running (details below). New Relic-admin Python directory: '/usr' current Python directory: '/home/isucon/local/python' New Relic-admin Python version: '2.7' current Python version: '3.8' * Serving Flask app "app" (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: on * Running on http://0.0.0.0:1323/ (Press CTRL+C to quit) * Restarting with stat
一方のInfrastructureのMySQL Integrationの方は、DB担当のkoyapigとの連携不足で、MySQLのbind-addressがanyじゃなくてNICのIP指定になってることに気づかずに、ローカルホスト指定でエラーになっていたことで導入まで時間をようしました。
Logsは今回初めて利用させていただきましたが、Appやログごとのフィルタが直感ではできず、Datadog logsに慣れた身からすると少しばかり使いづらかった印象があります。(私の慣れの問題も大きいと思いますが)
New Relic APMについては弊社のメインサービスでも活用しており、メトリクスを取得し始めてからの活躍は素晴らしいものでした。フル機能をISUCOM向けに提供してくれた New Relic さんの懐の深さに改めて感謝をいたします!
Netdataの導入
Netdataは導入したものの正直活用はできませんでした。 Netdataについて簡単に説明すると秒間でメトリクスを取得する高機能モニタツールです。
Netdataは大量のメトリクスのグラフを縦に表示してくれるため「よくわからないけど重い」時に何かヒントになるかもしれないと思って入れましたが、大幅なポイント増に繋がる情報を読み取ることはできませんでした。(これも利用者側の慣れだと思います)
Nginxチューニング
Nginxに関してはBot対策の力技設定を入れたのと、競技終了直前にaccess logを/dev/nullに出すことでIO負荷を少しでも減らそうとしました。
プロダクションだとあり得ない様なチューニングもやってみるか!となるISUCONならではの楽しさがでた瞬間でした。
# /etc/nginx.conf access_log /dev/null main;
メトリック/ログ監視
New RelicとNetdata、およびアプリケーションのログを眺める係をしました。エラーが出たらすぐに戻す判断ができたし、重そうな処理についてアラートをチームメンバに出すなどをしましたが、もっとログを分析するべきだったし、出力する情報も増やす動きを取れば良かったです。
OSチューニング
OSチューニングと書きましたが大したことはやっておらずです。 初期状態ではApp、DBが全サーバで起動した状態ですので、不要なプロセスを停止したりしました。
カーネルパラメタの変更が今回有効だったかは今の時点では思いつきませんが、もう少しOS観点でのチューニングができればと思いました。
次へのコメント
次回も機会があれば参加したいと考えています。 今回のモニタリングツールの導入やログ監視などの動きは悪くありませんでしたが、次回は直接スコアにつながるような動きを取りたいと考えています。
加えて、もっとアプリを触り倒してコードもちゃんと読み切るのも次は行いたいです。 /api/nazotte
が重いことは早い時間帯でわかっていましたが、アプリ担当のutautau16に任せっきりでそこはちょっと申し訳なかったなと反省しています。今回はPythonを選びましたが次回はGoを選択したい気持ちがあり、業務でもGoを利用する機会を入れていきたいですね。
まとめ
初めてのISUCON参加は、期待以上に濃密で楽しく、あっという間に時間がすぎました。 開始前後のDiscordでの盛り上がりもとても楽しくて学びの多いものでしたし、この経験がIT技術者としてのモチベーションをさらに高めてくれたと感じています。
このような機会を提供してくれた全ての関係者に感謝をしつつ、次の機会も是非参加したいと考えています。
ISUCON運営の皆様ありがとうございました!!
*1:それと、地力が試される良問でしたので、直前で多少素振りしてもそこまで状況は変わらなかった気がしています...