Souta Tech Blog.

ISUCON12に出場してみた投稿日: 2022年 7月22日

英語勉強の真っ只中で念願のISUCONに出場してみた

お久しぶりです。
そして現在も絶賛英語の勉強を継続中です!!
けれど、今日の1日だけはエンジニアリングを試したい!そして楽しみたいと思う気持ちからISUCON12にインターン時代の友人たちと一緒に本日出場してきました!
その備忘録とやり残したことのまとめです🏆
(これは自分の知識内だけで書いているので間違いなどがあれば教えていただけると幸いです。)

そもそもISUCONとは

公式サイトはこちらから!
とされていまして簡単に説明する

SUCONとは、LINE株式会社が運営窓口となって開催している「お題となるWebサービスを決められたレギュレーションの中で限界まで高速化を図るチューニングバトル」です。

とされているらしいです。(自分も詳しくはわかっていません笑)
ただ本来の題名としてはISUCON(いい感じにスピードアップコンテスト)という略になっているらしくて年齢関係なくプログラミングに興味がある人は誰でも参加できる大会です。
その文もちろんエントリーも激戦なのですが。。。。

経緯

前にインターンをしていた同期たちと共に「社員さんたちがISUCONに出場するらしい!」みたいなことを聞いて自分たちも出てみたいねなんか話していたらまさかのそのうちの一人が申し込んでくれといてくれました!!しかもガッツリと当選しているという。。。。
本当にその時応募してくれた方と一緒になって話を進めていただいた方、そして誘ってくれた2たりには感謝をしています!

メンバー

自分たちは最大人数である3人チームで出場しました。また、このご時世ということもあって当初は集まってやろうとも思っていたのですがそれぞれが個人のオンライン環境であるという形式にしました。正直自分は昨日まで英語にフルコミットしていてプログラミングするのも久しぶりでメソッドや概念や規約そのものを忘れていましたが他の2人が意味わからないぐらいアルゴリズム力がハンパないだけではなく地頭もいいので脳内で高速処理しているし、自分の意見や考えを尊重してくれてアドバイスをくれたり根っからのいい人たちので本当に支えていただきました。スコアの向上に関してもあまり自分は今回は関与することができなかったので自分にとっても悔しいですがせっかくのすごいいい経験だったので今後はもっとパフォーマンスのチューニングができるような技術力を英語の勉強が終わったら今まで以上にプログラミングに時間を費やしたいと思いモチベーションの向上につながったと思います💻

Go言語の選定

ISUCONは様々な言語で挑戦することができるようになっているような競技になっています!!
自分たちは過去のISUCONの実績や今のスキルセットなどを考慮した結果Go言語にしました。
自分の半年前ぐらいにはかなり記述していたのですが最近はもっぱらプログラミングそのものをやっていないというのもあって全然書くことができませんでしたが、Goのコンパイラがそもそも優秀っていうのもあるしフレームワークに関しても自分の経験のあるものでサーバーのバインディングをしていたのでとても取り組みやすく今になってはとてもいい技術選定だったと思います。そして他の方々もしっかりと使いこなしていたのでさすがだなと思ってました笑

備忘録

まず第一に感じたのは今までのやってきたいわゆる実装という部分とはかけ離れているのかな?というところです。
自分の場合は個人のプロダクトなら尚更なのですがアーキテクチャーに時間をかけてどれだけわかりやすいコードを書いて機能を実装するかどうかという部分にフォーカスして集中しています。しかもパフォーマンスに関するところも自分がデーターベース周りに関わっていたことが多かったり技術的にやったことがあるものを使って使いまわせるといった課題というより0→1を自分で作っていくような感覚だったのですが、ISUCONに関してはどのようにパフォーマンスを上げられるかどうか?というところの一点に集中しているのでもちろんコードをきれいに書くことに越したことはないですがそれ以上にチューニングをしてスコアをとっていかなければいけない、さらに時間になって初めて課題を見ることができるような仕様なのでアプリケーション全体のイメージ感を掴むのにも時間がいるということもあってそこら辺はどちらかというと問題という表現の方が近かったような所感です。
全部紹介することはできませんのでかいつまんでになります。実際に他の2人は自分が把握していること以上のことをやっていたので理解できていない部分のあります。すいません笑

環境構築

これも大変な部分の一つだと思います。もちろんこの開発は一人で行うものではないのでDockerなどのコンテナの環境ですることもできるのですがサーバーを利用するために踏み台サーバーと本番サーバーなどを用意しておくことなどが求められます。これが普通に大変というか人数分に合わせて作成しなければいけないだけではなく、本番を想定して練習サーバーでもSSH接続をすることができるのかどうかなどやKeyの登録などやることがかなりあります。
これに関してはチームメンバーの方が事前に様々な設定をしてくれ、しかも当日にはMakefileなども作成して必要コマンドをAlias化してくれるような化け物っぷり。。。怖いと思いつつ全力で頼らせていただき、当日のインフラ環境及びサーバー関連に関しても全てやってくれたので本当に開発に集中することができました😇

データーベースチューニング

これはまず必須だと思います。というのもインデックスを利用することで本の検索のようなものができるようになるようになりテーブルを処理するためのデータ構造を高速化することができるようになっています。なので、特定のカラムの検索をする場合に調べたい項目がわかり、検索を高速化できるという仕組みです。
詳しくは「SQL INDEX」のように調べてみてください、記事が出てくると思います。
これに関してもデーターベースの理解やINDEXはしっかりと理解した上で利用しなければ逆にパフォーマンスが下がってしまうこともあったりするのでそこの部分も考慮しなくてはなりません。これに関してももう一人の友人が全てやってくれました。しかもそれでしっかりとスコアを向上させていく優秀さ、トラブルに関してもとても冷静に解決されていたので自分が見習うべきことがたくさんあるなと思った点とまだまだ理解が浅いなという点でした。

接続データベースの切り分け

デフォルトとして踏み台サーバーの方にデータベースサーバーとアプリケーションサーバーの両方が構築されており、データーのInitializeなども全てそのファイルに完結されるようになっているのでそこの部分をより高速化されたサーバーに切り替えるとINDEXが実装されたテーブルを利用することができると考え実行しました。これに関しては自分が担当しましたが想定よりも自分のイメージとの剥離があり、元々想定していたデーターベースなどでもなかったためかなり困難することができましたが依存変数などの定義などをみてみると答えが見えてくることなどもあってかなり汚く力技でしたが実装することができた?と思っています。しかし実際に完璧に動作検証することができたかというとそうではなく(もちろん時間内には厳しいことはわかっていたのですが)もっとここら辺のインフラ部分のアーキテクチャなども落ち着いたら勉強しなければいけないという自分に対するボトルネックを発見することができたとてもいい経験でした!!

N+1クエリ問題

これに関しては以前インターンしていた企業でRubyを利用していた先に全ての大きいデータの部分でテーブルの構成をいじってどのような時にJoinさせるのかどうかということをよくやっていたので関連テーブルの扱いなども慣れていると思ったのですが、Go言語でどのように関連テーブルにアクセスするのか?そしてのどのように利用してパフォーマンスの向上につながるのか?ということを忘れていた反面、対策不足ということもありあまり実行できませんでした。多少の部分はもちろん実装できたのですがそれ以上に過去にかなりできたからってたかをくくっていたかもしれません。久しぶりにやることはしっかりと復習をしてから取り組むようにしたいです…

課題

もちろんたくさんの学びの場でもありましたが、反省の場でもあります。
そして今まで自分にできなかったことや逃げてきたことが少しでも浮き彫りにあるようなことがたくさんあったのでそのこ部分もしっかりと復習できればと思ったとともに今でもわからないようならしっかりと学習を復習して進めておくべきだと改めて実感することができるようなとてもいい機会だったと思います。それにしてもここまでできないとは思ってなかったです笑

キャッシュ問題

これに正直自分が担当させていただき午後は時間を一番使って考えていたのですが、時間内までに解決することができませんでした。開発中に考えていたこととして時間内に実装できるライブラリや簡単なキャッシュ処理なら自前で実装なども視野に入れていて

  1. Redisなどのインメモリデータベースを用いたキャッシュ(以前のインターン先で経験済み)
  2. データそのものにキャッシュ機能をかける(正しくはフレームワークそのものに利用)
  3. サーバーに利用(これも同様にフレームワークサーバーにバインドして利用)

の三つを考えていたのですが、これを実装して行ってみた結果、テストそのものがデータの一致から判断している部分の問題があってスコアそのものの前にベンチマークテストそのものを利用することができないという結果でした。よく考えてみるとキャッシュのデータの対象として1MBのデータをキャッシュするというものを利用していましたが毎度変更を感知するようなアルゴリズムが実装されていると現在考えておりキャッシュされたデータを優先的に利用される仕様になっていたため実際のテストデータとの差異が生まれてエラーが起こってしまったと考えております。この部分は本当に難しくデータベースというより低レイヤーの部分もたくさんと絡んでくると思うのでどっちにしろ勉強不足です。。。

トランザクション

これは完全に忘れていたということでした。確かにコードを見るにデーターベースにアクセスしていて一つでも止まったらロールバックするような実装はされていなくもしあれでバグなどがあったらどうすることもできなかっただけではなくデバッグの際にも本当に役に立つと思うのでしっかりとここの部分は日頃から大切なデータだからこそ利用する価値があると改めて実感することができました。

リバースプロキシ

これに関してはいまだに理解することができません。どちらかというとアプリケーション動向値うより外部のインターネットからサーバーへアクセスされる通信を中継する仕組みとなっておりフィールドプロキシと比較すると接続される方向が逆になる。。。となんとも難しい言葉を並べておりますが自分も理屈しか知らなくて実際にこのプロキシを利用したことがあるかというとそもそも普段から意識したこともなかったので勉強になりました。今後エンジニアとして成長していくには必要なことだなと感じました〜〜〜

感想

総評して心のこそから今回の大会には出れることができてまずよかったなと思っています。そして一緒に出場してくれた2人に本当に感謝をしたいと思っております。肝心の結果に関しても自分では絶対に達成することができないようなスコアを発揮することができたので本当に優秀なんだと思っています。2人のようなエンジニアリングを目指していけるようにしていきたいとともに自分にしかない強みもエンジニアとして何かしらはあると思っているので(ドキュメントを読んでその技術を取得するのがとんでもなく早いです笑)それをこれからどのように活かしていきたいのかを改めて考えていこうとおもいます。
そしてまた機会があれば出場したいと思います!!!!