logica氏の自己紹介

logica氏(以下、logica):(みなさんが)待っていたかどうかはアレですが。「開発を愛する人」。これは僕のことですが、「(開発を愛する人)が最高にISUCONを楽しむ方法」ということで、話していきたいと思います。

初めまして、logicaです。僕も「わっしょい!」とかやりたいと思ったのですが、話すことが多すぎて遊ぶ暇がないです。

軽く自己紹介します。logicaと言います。traPというサークルに所属していて、「traQ」という、traPが管理しているOSSの中では一番大きなサービスである「メッセージングサービス」のバックエンドメンテナンスのリーダーをしています。ISUCON歴はISUCON11で予選敗退して、traPに紹介されて入りました。

予選敗退のあとISUCON12では学生枠で決勝進出して、一応13位ぐらいまでは行きましたが、そんなに輝かしい成績という感じではないです。2022年本選の録画を見てくれた人はわかると思うのですが「作問運営になりたい」と公言している、たぶん世の中に数少ない狂人の1人です。とにかく開発が大好きな人です。

余談ですが、「ISUCON夏祭り」という企画は僕の発言から出た可能性があるということのポスト(ツイート)だけ貼っておきます。

「ISUCONferenceというイベントをやらない?」みたいなことを「Twitter(現X)」で呟いたら、941さんが「検討します!」と言ってくれて、その1年後ぐらいにこのイベントが開催されました。すごく光栄だなと思っています。

ISUCONは「Dev」か? 「Ops」か?

logica:本編に入っていきましょう。「ISUCONはDevですか? Opsですか?」ということに対して自分なりの解釈をしたくて。適当なところから出典を取ってきてしまっているのですが、Devは機能の開発を担当するほうで、Opsは現在動いている環境を維持し、サービスを安定して継続するほう。

ISUCON自体、ISUCONの競技者の視点から見ると、サービスの本質を変えないのでOps、要は「運用方面だ」と言うことができると僕は思っています。

でも、「僕は開発が好きです」と、先ほど公言したとおり、開発がめちゃくちゃ好きなので、ISUCONを解いているだけでは物足りなくなってきちゃうんですよ。ISUCONを解いているだけでは物足りない。じゃあISUCONをテーマに「何か開発しないと!」。「開発しないと!」までいかないけど「開発したい!」と思うわけです。

ということで、約2年間ぐらいあるISUCON歴の中で3つのものを作ってきたので、今日はこの3つの「ISUCON駆動開発」の歴史を紹介していきたいと思います。

ISUCON駆動開発「Remote-BMI」

logica:まず1つ目です。「Remote-BMI」というやつです。ISUCONの練習時に使える、簡易的なベンチマーカーWebUIということで作りました。

ISUCON練習時のベンチマーカー操作は、ダッシュボードがないという問題があるんですね。個人練習やチーム内で練習する時などを想定すると、公開されている公式ポータルをデプロイするのはあまりにも大変だし、そもそも個人向けに作られていないので、機能が多すぎるという問題があります。

そうすると選択肢として取れるのが、CLIでコマンドを叩くことです。要は、ベンチマーカーのコマンドを叩くことしかなくて、ベンチマーカーのためだけに、いちいちSSHで入るのは面倒。特に競技サーバーとベンチマーカーのサーバーを分けて、本番さながらの環境でやりたいという時には面倒です。

それに、ベンチマーカーのログはCLIで叩いていると揮発するので、Issueにわざわざコピペして管理したり、保存を自分でやらなきゃいけないということがあって。公式ポータルとCLIでコマンドを叩くことの間のソリューションが欲しいんですよ。

というところで「Remote-BMI」があります。

(会場拍手)

察してもらえて何よりです。ありがとうございます(笑)。簡単に使い方を説明します。サーバーを登録します。サーバーを自動で検出する機構などはないので、自分でアドレスを登録します。

サーバーは3つまで登録できるのですが、これは2022年の本選があったから、5個まで増やさないといけないのかなと思っています。

3個まで登録できますが、公式ポータルとだいたい同じ感じで、1から3まで選んでベンチマークの宛先を指定して、ベンチマークを回すことができます。

ログも閲覧できます。ログの裏でMySQLがバックエンドに接続していて、MySQLにログがぶち込まれるかたちになっています。「Remote-BMI」はMySQLにログが残っている限り、各回のログが全部見られる感じになっています。

ログが見られるところを画像にしたかったのですが、ちゃんと環境が立てられなかったというのがあって。(スライドの)下に黒い四角で囲まれている小さいところがあるのですが、そこが一応ログが表示される場所になっています。

ここでちゃんとベンチマーカーの標準出力のログが見られる。競技者が見れるようなログのみが、ここで見れるようになっています。

「Remote-BMI」に対して今後やりたいけどまだやれていないことに、デプロイが面倒くさいという問題があります。リポジトリをクローンしてビルドするか、配布バイナリを持ってくるというものしか用意していないんですね。ちょっと面倒くさがってこのあとをやっていないという話で(笑)。

いずれにせよ、設定をあとからやらないといけないので、今は非常に面倒なデプロイ方法になってしまっているというところがあります。

設定なしでコマンドを叩けばすぐに使えるのが理想で、DockerイメージをCDとして、コンテナレジストリにビルドとプッシュを自動的に行い、docker-composeでデプロイまで一発で行ければいいなぁと思っていますが、やる時間がいつ取れるかがわからないです。

というわけで素振りの効率Upにぜひ! 「素振りが大事だ」というお話しがありましたし、たぶんこのあと素振りの大切さをたくさんお話しされると思うのですが、素振りの効率Upにぜひ。素振りの支援ツールを発表するのはたぶん僕ぐらいだと思うので、ぜひお使いください。ということで1つ目のRemote-BMIが終わりです。

ISUCON駆動開発「helpisu」

logica:2つ目の「helpisu」に入ります。helpisuはISUCON helper library for Goというテーマで僕が作っている、ISUCONの時に使えるユーティリティ、スニペットなどを置いてあるGoのライブラリになります。

Goの人にしか使えなくて申し訳ないのですが、みなさん、こんなことありませんか? 「キャッシュを書くのがだるい」「定期実行ってどんな感じで書くんだったか忘れた」「UUID・ULIDの生成方法を忘れた!」「なんかライブラリのドキュメントを調べなきゃ!」。すべてhelpisuが解決できます。特筆すべき機能をこのあと紹介していきます。

まずはキャッシュです。実態はsync.Mapのジェネリックなラッパーです。いろいろな人がやっているやつですね。ジェネリクスという機能がGoの1.18で、たぶん2022年、2021年ぐらいに追加されて、あらかじめ型を指定して固定することができるようになりました。sync.Mapという公式のスレッドセーフなマップのライブラリにはそれがないので、自力でラップしました。

あと、他の人たちがやっているかいないかはわからないのですが、ResetAll()という関数があります。これが全キャッシュ削除のAPIを持っています。生成したキャッシュをパッケージ内のグローバル変数として、リストで持っているんですね。

アプリケーションの初期化時に状態を全部リセットしたいという需要に対して、ResetAll()という関数を1つ叩くだけで、漏れなくリストに入っているキャッシュのインスタンスに関してはすべて初期化されるように実装しました。これによってキャッシュの作成時にリストに配置されるので、抜けがないという感じです。これはけっこう便利で重宝します。

続いてDB系のユーティリティです。WaitDBStartUp()という関数があるのですが、これは引数で渡したDBのインスタンス、構造体の立ち上がりまで終了しない。要は、立ち上がりまで待ってくれる関数になっています。

methaneさんという方のブログを見ている方はけっこう多いと思うのですが、DBの立ち上がりを待つというブログを参考に、それをユーティリティライブラリ化したかたちになります。

(スライドを示して)下にあるDBDisconnectDetectorというやつがそれの逆で、DBが切れた時、DBとの接続が実際に切れても、GoのSQLのライブラリでは検知できないんですね。自動で検知はしてくれず、切れてもインスタンスというか、コネクションが張ったままであると勘違いして、そのままそのDBにアクセスしようとするとエラーで落ちるということが頻繁にあるんです。

これが再起動試験で、いつも起こる。再起動試験で参加者を泣かせている仕様の1つなのですが、それに対処するため、DBが切断された際に強制的にアプリケーションを落とすということをするものを作りました。

ベンチマーキング中に、基本的には一定時間ごとに「DBに接続している?」と、ちゃんとコネクションが張ってあるかを聞いて、張っていなかったら落とすかたちになっています。ベンチマーキング中にできるだけ負荷をかけないように、一時停止の機能も付けました。

続いて定期実行です。GoのTickerというものがあります。一定時間ごとに「一定時間経ったよ」ということをお知らせしてくれるTickerというものがあるので、それを使って関数を定期実行することに特化した機能を持つ「Ticker」というものを作りました。

(スライドを示して)新規作成時にインターバルをintで指定して、func()で関数を渡して、その関数をインターバルごとに実行するというのが、これです。あとは全部良い感じにやってくれます。

(スライドを示して)これが恐らくこのライブラリ内でトップレベルの狂気を持っているNewUUID()とNewULID()という関数で、ライブラリのDocsを見なくても一瞬で実装できるように、わざわざUUIDとULIDのライブラリをラップしているだけです。ただの狂気です。

今後実装したい機能は時間がないのでパッと飛ばしますが、「Cache Sharer」というキャッシュをシェアするという機能と、「fibec」というWebフレームワークの載せ替えを一瞬で行うためのライブラリを作ろうと思っています。ただの狂気です。

ソースコードは公開しているので、もしGoでISUCONを解いている方がいたらぜひ使ってみてほしいです。

これを使って僕より強くなられるとちょっと心が辛いですが、僕も負けないようにがんばりたいと思います。

ISUCON駆動開発「gasshuku-isucon」

logica:最後の項目になりました。「gasshuku-isucon」です。これはお察しの方もいるかもしれませんが、logicaが送る初めてのオリジナルISUCONということで、やらせてもらいたいと思います。ありがとうございます。拍手を。

(会場拍手)

私を知っている方は知っていると思いますが、以前から「作問したい、作問したい」と言っており、初めてのオリジナルISUCONをこの場で公開することになりました。時系列はパッと飛ばしますが「ISUCONの作問者運営になりたい!」と言ったら、941さんたちに「とりあえず1問作ってみたら?」と2022年の本選配信で言われました。

2023年2月にtraPで春合宿が行われたんですね。その春合宿で部内ISUCONを開きたいと思って急ピッチで制作を進めたのですが、2週間ほどですべての枠組みを組み終え、どうしてもベンチマーカーがうまく動かないまま放置をしていたところ、2023年6月にcatatsuyさんと対面でお話しする機会をもらいました。

そこでヒントをもらったのですが、結局いろいろな開発やらインターンやらがあって何もできず、昨夜一晩でなんとか遊べる状態まで持っていきました。めちゃくちゃ寝不足です。

ということで公開していきましょう。

SettingsからChange visibility。公開されました! ありがとうございます。

会場:おぉー!

というわけで今パブリックになったので、これでみなさんも帰ってからすぐに遊べるということですね。(スライドを示して)遊び方はここに書いてあります。

プロビジョニングのスクリプトなどはまだぜんぜん書いていなくてガバガバなので、実力のある方々は適宜察して動かしてもらえると何よりです(笑)。

ずっとX、旧Twitterで「@ISUCON作っています」というSuffixを付けていましたが、今日でようやく取れるということになりますね。

「gasshuku-isucon」のテーマ、図書館管理システム「isulibrary」

logica:ということで、最後にちょっとだけテーマについて。この問題のテーマについて話をさせてもらいます。紹介して、みなさんの興味を引ければと思っています。

今回作ったアプリケーションというのが、図書館管理システム「isulibrary」です。会員管理と蔵書管理、貸出管理という3つに機能がカテゴライズされるサービスになっています。延滞しすぎた人をBANする機能も付いていて、エンドポイントが12、13個ぐらいの……。最近のISUCONに比べればそんなに大きくないアプリケーションです。

想定しているユーザーは2つのアクセス経路があります。図書館のシステムって、みなさん触ったことあります? 僕は最近図書館に行ってなさすぎて小学生ぐらいの記憶を頼りに作っているので、今とはちょっと違うかもしれないのですが(笑)。

図書館内の蔵書探索専用端末からのアクセスと、図書館職員の端末、図書館の職員さんが触っているパソコンですね。全機能にアクセス可能な端末の2つからユーザーのアクセスがあることを想定していて、個人端末への静的配信がないというのが今回の問題の最大の特徴です。

この他にもすばらしい成果を上げていますが、このスライドではそれを語るには狭すぎるので、詳しくはリポジトリをじっくり見てもらえれば何よりです。

今後やりたいことは、競技ルールが定まっていないのでドキュメントの整備をするのと、プロビジョニングスクリプトで、みなさんが同じ環境で解けるようにすることですね。あとフロントエンドの整備。フロントエンドの静的配信がないことに甘えてフロントエンドの整備を行っていないので、ちゃんと作らないとなと思っています。

みなさんに協力してほしいことがあります。これから遊んでくれる人は遊んでくれると思いますが、ぜひ遊んでください。ぜひ楽しんで遊んでください。みなさんに楽しんでもらって、X(Twitter)などで感想を呟いてもらえると、僕が喜びます。

あとは、バグや粗の報告をしてほしいです。ベンチマークのバランスが非常に今はガバガバなので、フィードバックをもとに改善していきたいと思っています。

また、今はGoしかバックエンドの参考実装がないので、ぜひ他の言語のプロのみなさま、移植を検討してもらえると幸いです。

というわけで、よき「ISUCON駆動開発」ライフを。ありがとうございました、logicaでした。