takonomura氏の自己紹介

takonomura氏:では「ソロISUCONの戦い方」ということで、takonomuraが発表します。よろしくお願いします。最初に軽く自己紹介ですが、takonomuraといいます。筑波大学で学生をやっていて、大学院の入試が今週(登壇時点)あって、ちょっとあたふたしてけっこう忙しかったです。

ISUCON周りだとTeam takonomuraという謎の1人チームに所属しています。実はTシャツも作っていて今着ていたりもしますが、そういうことをやっています。

(スライドを示して)ISUCON歴は、ISUCON8の時に初めて参加して、その時は3人チームで出て予選で落ちてしまったのですが、その次の年のISUCON9の時に、チーム構成の問題などもあって1人チームで出るようになりました。その時に予選で1位を取れたり、本選でも準優勝を取れたりして、けっこういい感じでできたなというのもあり、それからは1人チームで出続けています。

ISUCON10の時に優勝して、11の時に作問。2022年も一応出て学生2位で、ISUCON9以降は本選も行っている感じでやっています。

「ソロISUCON」とは何か

今回の発表内容はソロISUCONの戦い方ということで、ソロISUCONとは、勝手にそう呼んでいるのですが、1人のチームでISUCONに出ることを指しています。

そもそも1人のチームはISUCON8から解禁されたもので、ISUCON7まではどうやら2人以上が条件になっていたようです。

これは「そもそも1人だとなかなか勝てないだろう」みたいなのもあって存在した条件みたいで。自分もけっこう同意できるので、ソロISUCONで1人で出ているわりにはほかの人におすすめはあまりしないです。理由がないんだったら3人で出たほうがいいんじゃないかなと個人的には思っています。

ISUCONにソロで出る4つのメリット

でも、そんな中で自分がどうしてソロで出ているのかという話ですが、いくつか利点もあります。

1つ目がメンバーを探さなくて済むことです。ぼっちの人とかはけっこうメンバーを探すことに苦労することもあります。実務的なというか、実際にやる時の利点としては、そもそも作業がコンフリクトしたりすることがないということがあります。

3人チームだと、8時間という短い中で同時にいろいろな作業をすると思うのですが、場合によっては、その作業が被ってしまうせいで同時にはできないから順番をずらさなければいけなくて、暇ができちゃう。そうなると大変だったりするのですが、1人だったらコンフリクトすることは当然ないです。

コミュニケーションのコストが要らないのも利点になってきます。やはりチームでやっていく中だと、チームの中でうまく情報を共有していくのがISUCONの中では重要だと思います。

しかし、それはなかなか大変なことであって、うまくやらないといけないことでもあると思います。ですが、1人でやったらそういうことはないので、すべてのことを自分が知っているし、すべてのことを自分がやるみたいな感じになります。

最後に、これが一番大きいかなとは思うのですが、インフラ、アプリ、DBとか、ISUCONのすべてを自分でやれるのが利点だと思っています。逆を言えば、すべて自分でやらなきゃいけないという欠点にも聞こえるかもしれないですが、自分にとってはけっこうな利点です。

3人チームでやると、作業のコンフリクトとかをしないようにするために、インフラ担当とかアプリ担当、データベース担当みたいにメンバーの中で担当部分を分けることがけっこうあると思います。

そうすると、自分が全部やりたくてもやることがどうしてもできないという中で、1人だったら全部独り占めできるという点では、それが利点かなと思っています。

ISUCONにソロで出るデメリット

とはいえ、当然1人でやることにはデメリットもあります。「それはそう」という話ですが、3人分のことを1人でやらなければいけないんですよね。時間は一緒なのに人数が少ないので、当然やることは多くなる。とにかく時間が足りなくなります。本当に足りないです。

あと、けっこう大きいかなと思っているのは、視点が1つしかないことです。8時間という短い中でやらなければいけない時は、ミスなどがあった時にすぐ気づかなければいけないんですよね。

3人だと「うーん」って悩んだ時にも、ほかのメンバーに聞くことで「こうなんじゃない?」とすぐに気づけたりするかもしれないのですが、1人だとなかなかそうもいかないので、ミスがあっても引きずってしまったり、そもそもいい解決策が思いつかなかったりして、知識的にも、ミスがあった時の視点的にも足りなくなりやすいです。

今回の発表では、そういったデメリットを軽減するためにも、自分がどういうふうに取り組んでいるか、考えていることなどを話していこうかなと思っています。

重要なのは「自分に合った戦い方をすること」

この発表でなにを話そうかなと悩んだのですが、具体的なテクニックは人によってさまざまというか、それこそソロで出ない人も多いと思うし、話してもアレかなと。なので、具体的になにをやっているかというよりは、どういうふうに考えて取り組んでいるかみたいな、考え方のほうをメインで話していきたいなと思っています。

今回話すことは、ソロで特に重要だと思って考えていることではありますが、チームでやっている時にもけっこう活きてくると思うので、そういう人たちにも参考になるような内容になっているんじゃないかなと思います。

話すことはけっこう「当たり前だろ」みたいなことばかりになる気もしますが、「当たり前だけどそれが重要だから当たり前になっている」みたいな話でもあると思うので、けっこうそうなるかなと思っています。

一番重要かなと思っていることが、自分に合った戦い方をすることです。というのも、他人にとって最適な戦い方が自分にとっても最適な戦い方であるとは限らないと思うんですよね。

他人を真似するだけでは優勝することはどうしてもできないんじゃないかなと思っていて。真似をすることも悪いことではないと思うのですが、そこからさらに発展的にいろいろとやっていく必要があるかなと思っています。

他人のブログを読んだり、セッションの発表を聞いたりしてそれを参考にする。その中で「こういうのは自分の性格にはあまりにも向いていない」というのもあると思うので、その中から自分に一番良いものを選択したり、場合によっては、「この人はこうやっているけど、こうしたほうが自分には向いているかな」みたいなアレンジをしたりしていくのが重要になってくるかなと思っています。

また、今回のセッションやISUCONのブログ記事はいっぱいあると思うのですが、そういったもの以外にも、日々の生活や開発をしている中からも、いろいろと参考にできることは多くあるかなと思っています。

「ISUCONだからISUCONの中でいろいろと考えていく」というだけじゃなくて、もうちょっと広い視点でというか、日々の開発の中からも、どういうものがISUCONに活きるか、どういうところがISUCONと近いのかみたいなことを考えながらやっていくのが、戦い方を見つけ出していく上ではけっこう重要になってくるのかなと思っています。

「そういったことを言ってもなかなか戦い方を見つけ出すのは難しいんじゃないか」と思うのですが、実際にそれをやるのは、練習と振り返りを繰り返していくことしかないのかなと個人的には思っています。

練習の時には高いスコアを出すことが目的になってはいけない

なので、練習をいろいろとやって、過去問などで素振りしていこうという話だと思いますが、個人的には、その練習の時に高いスコアを出すことが目的になってはいけないのかなと思っています。

基本的に本番でより良い結果になるために練習をしているんだと思うので……。練習で結果が良くても本番の結果が良くなかったらだめじゃないですか。となった時に、本番はやはりぜんぜん違う問題が出てくることもあるということを考慮すると、単純にスコアだけが練習の目標になるのは違うんじゃないかなと思っています。

練習の時は振り返りをすることが大事だと思っていて、振り返りの結果としてどのようなことが本番に活かしていけるのかを考えていく必要があると思います。

そういうことも考えると、できる限り本番と近い環境で練習したほうが本番に活かせることが多いんじゃないかと思うので、1週間、2週間、同じ問題をずっと解くのはいろいろな改善案を知っていくという点では大事かもしれませんが、本番は8時間しかないのを考えると、本番と同じ競技時間でやってみるとか。

先にブログなどで解法を知ってしまうよりも、知らない状態でやった時に自分がうまくボトルネックを探せるのかが大事になってくると思うので、そういうことを練習してやっていくのが重要になってくるんじゃないかなと思っています。

時間を効率的に使うために、事前にやれることは全部事前にやる

次に、時間を効率的に使うための話をしていきます。先ほども言ったように、3人分のことを1人でやらなきゃいけないので、とにかく時間がないんですよね。とにかく時間がないので、効率化を図らなきゃいけなくなります。

どういうふうに効率化を図るかということで、すごく当然なことですが、事前の準備を徹底していくのが大事になってきます。事前にやれることは全部事前にやるということで、例えば「GitHub」のリポジトリを先に作っておくことはたぶんすぐできるので、とりあえずやっておくとか。

リモートなどで参加する時によくあったんですが、ランチの準備を先にやっておくことで、買い出しにいく時間を削減するとか。本当にできることから全部やっていこうという感じですね。

また、「絶対やること」だけを準備しておくのではなくて、「絶対に使うかはわからないけどこれを使う必要があるかもな」みたいなこともいろいろ準備しておくのが大事になってくると思います。

競技時間中にやったことがないことをすぐやるのは難しいということは、ほかの発表でもいろいろと(その話題が)出ていると思います。

そういうことのためにも、本当に本番で出てくるかわからないにしても、いろいろなライブラリを知っておいて、このライブラリを使わなきゃいけなくなった時にも使えるようにするとか、データベースも「MySQL」ではなく「SQLite」が出た時にも使えるように触っておくとか、いろいろなことを触っておくのが、けっこう重要になってくるんじゃないかなと思っています。

そういうのを準備することも、練習を通してやっていくことが重要になってくると思います。特に8時間でやってみると、8時間でやる時になにが時間がかかるかみたいなことがわかると思うので、8時間の練習を繰り返していくのが重要になってくるんじゃないかなと思っています。

自分にあった便利なツールやサービスを活用する

次に、便利なツールやサービスを活用するということがあると思います。これはみんなやっていることだとは思いますが、その中で重要なのは、自分に合ったものを探していくことだと思います。

いろいろな機能があるものだったり、知名度が高いものだったり、いろいろなツールとかが世の中にあると思うのですが、それだけじゃなくて、自分にとってどれがどう使いやすいのかとか、どうわかりやすいかみたいなところは、ISUCONで使う中ではけっこう重要になってくるんじゃないかなと個人的には思っています。

機能がいっぱいあるものの設定は複雑となった時に、「じゃあ、本番競技時間中にこういう設定しなきゃいけないけど、どうやったらいいんだろう?」とわからなくなることがけっこうあるので、機能が多いから選ぶというよりは、「自分にとってこれはわかりやすいからすぐ使えそうだな」みたいな感じで選んでいくのがけっこう重要になってくるかなと思います。

自分が使っているものだと、デプロイには「mitamae」「Itamae」系のやつを使っていたり、計測では「Netdata」を使っていたり、アクセスログの集計には「alp」を使っていたりします。あと本番環境のアクセスのためには「sshuttle」、SSH経由でVPNみたいなのを快適に張れるツールがあります。

全ポートSSHでアクセスしなきゃいけなくて、ポートフォワードとかを毎回設定するのが面倒くさい時に、これを使うと一括でアドレスレンジをVPN的にSSH経由でつなぐみたいなことができるツールがあって、そういうものを個人的には使っています。

こういうふうに、自分にとってどういうのを使ったら一番いいのかを考えながらやっていくのが重要かなと思います。

自動化できるものは自動化をしておく

これも当然のことで、自動化できることは自動化しておこうということです。やはり時間が足りないので、自動化できるものは自動化しておいたほうが早いという話です。

効率化できるというだけではなくて、自動化することのメリットとして、作業のミスが減らせることも大きいと思います。8時間の中だと作業のミスはけっこう致命的なものになりやすいので、ミスが減るという点でも自動化はすごく大事です。

自動化する時にけっこう気をつけていることとしては、当日の状況次第で柔軟に対応できることがすごく重要だと思います。「自動化はできたけれど、このような構成の時にしか動かないもの」みたいになってしまうと、ISUCONは本番になるまでどういう問題が出てくるかわからなかったりするので、想定とちょっと違う問題が出てきて、そのツールが全部使えなくなっちゃったとかすると、けっこう時間のロスになってしまいます。

なので、ちょっと違う構成が出ても、うまくその場合に応じて書き換えるだけで使えるように、柔軟に対応できることが重要だと思います。

それには、「すごく便利なものを持ってきた」というよりは、自分が全部理解できて、必要に応じて変更を加えながら使えるような簡単なもの、シンプルなものを選んでいくのが重要だと思います。

自分が自動化していることの例として、当然のようにサーバーの初期セットアップは自動化してあって、その中で計測ツールをインストールしたり。あと自分がやっているのは、GitHubにデプロイキーを自動で追加して、それをSSHでgit cloneできるようにするというのを自動でやっていたりします。

あとコードの一括置換として、自分が使っている計測ツールの都合上、データベースのクエリ実行などをする時に、GoでContextを渡すと、それをもとにいろいろとうまくデータを取ってくれるやつがあります。

そのためにDBのクエリを叩いている部分に全部Contextを引数として渡すようにするみたいな変更を全部にやらなきゃいけないんですが、これを手動でやろうとするとけっこう面倒くさいので、うまくGoのASTを解析して、型を見てみたいなことをやって置き換えるようなツールを用意しています。

あとは、当然のようにデプロイの自動化もやっていて、再起動したり、ビルドを行ったり、ログをローテーションしたりだとかが一発でできるようにしています。

あと、計測周りも、毎回コマンドが長いと意外と覚えられなかったりタイプミスしたりするので、短いコマンド一発でGitHubにコメントとして計測結果が出るようにしています。

無駄な変更をしないことも重要

ほかにやっていることは、無駄な変更をしないということにすごく気をつけています。過去の反省でも毎回「あぁ、この変更は無駄だったな」みたいなことがあったりするのですが、本当に時間がない時に思うのは、無駄なことを1個でもやると、それで時間を食って優勝から遠ざかっていくということなんですよね。

ボトルネックの部分だけを最適な改善策で直していくことだけを繰り返していくのが、ソロでやっていく中では必要になってくるのかなと思っています。

なので、そのボトルネックになっている部分をすぐに見つけられるようにするのが重要になってくるのと、改善策はたぶんいくつか思いつくと思うのですが、その中でどれが一番効くのかという判断をやっていかなきゃいけないと思います。

その中で推測が入ってきて、その推測が間違っていたりすると、やった後に「だめだった」となってロールバックしたりすることで時間のロスになってしまうので、できる限り早い段階で確信を持てるような根拠を持って取り組めるようにしていくのが重要になってくるかなと思っています。

あと自分でやっていることは、改善後にスコアがあまり上がらなかったりすることもけっこうありますが、その時は気にせず、ロールバックとかはしないようにするという考え方でやっています。

というのも、スコアが変わらなくてもボトルネックが別の場所に移っただけということがあって、ボトルネック自体が潰せたとしても、それに合わせてスコアが上がるかどうかは、状況によって変わってくると思います。

なので、スコアがどうというよりは、スコア以外で自分が「ここがボトルネックだろう」と思った判断材料となる計測結果が別にあると思うので、その計測結果を基に、「ここは直って別のところがボトルネックになったんだな」と判断ができれば、その変更は正しかったと判断する、ということをやっています。

(次回に続く)