ISUCON運営側として工夫したこと・改善点（※ 社内でやったISUCONの話）

この記事は [アイリッジ Advent Calendar 2019](https://qiita.com/advent-calendar/2019/iridge)の17日目の記事です。
昨日は @yacchin  さん の記事、「[GitHub Actionsを使ったECSデプロイ](https://qiita.com/yacchin/items/7bbb9c35fd84c1355f8f)」でした。

## はじめに

弊社では、[FANSHIP](https://www.fanship.jp/) というプロダクトを企画・開発しています。
FANSHIPの開発チームでは、月に１回まる１日、チームワーク向上のための時間（IssueBash）を設けています。

やっていることは様々で、ペアプロをしてみたり、新しいツールを使ってみたり、様々なことを行なっています。

今回、その時間の中でISUCONもどきをやってみたのですが、特に運営側でやったこと、工夫したことなどを書きます。

**公式のISUCONの話ではありません。**

## そもそもアイリッジの IssueBash とは

図にするとこんな感じです。
常日頃の業務ではシステムの健康を考え、自分たちがすべきことを行なっています。
しかし、システムを作っているのは担当するチームであり、そこに所属する個人です。

そのため、自分たちが健康的にアウトプットを出せる状況にいないと、当然良いサービスはできないであろうという考えのもとで、最近では特にチーム内のコミュニケーションを主軸とした取り組みを行なっています。

![967a32bd-71b3-49e5-9295-8e7daadc5ed4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49776/c7854afe-14a6-55b3-a801-c30d90365f42.png)


## ISUCONのお題


自分たちのサービスに実際にあるAPIを、お題のモチーフとしました。

```
株式会社アイリッジでは、FANSHIPというスマホ向けのサービスをリリースする。
FANSHIPは、PUSH通知を送る機能がある。
PUSH通知を受信後、スマホ端末はWebAPIを叩き、自分の「メールボックス」に存在するデータを取得する。

しかし、ここに来てパフォーマンス上の問題が見つかった。
上記のAPIは、遅すぎて大量のPUSH通知を送信後にサービスが止まってしまうのだ。

リリースは明日。このAPIをとにかく高速にしてくれ。
```



## 参加者にどんな学びがあったか
参加チームは、4名 x 3チームです。

ISUCONの後でアンケートを取ったところ以下のような学びがあったとの声が多かったです。

* 他の人の作業の速さにびっくりした（ターミナルや、エディタ、コードを書く速さなど）
* インフラ面の重要性を再認識した。インフラ側の知識が不足すると実感した
* うまい役割分担ができるとスムーズに作業が進められた。コミュニケーションの大切さを痛感

IssueBashの目的である「チームの健康・個人の健康」という観点では良い取り組みになったと思います。

このあたりは会社やチームの雰囲気によって変わってくると思いますので、ご参考までに。

## 運営側でやったこと

運営側と書いてますが、実質私１名が運営側です。
ISUCONの性質上、ネタバレできないので手伝ってもらうことができず１人で用意しました。

### 工夫１：ベースとなるコードの設計を実際のプロダクトから拝借した
実際のプロダクトから取ってくることで以下のような効果を狙いました。

* 参加者が、仕様理解に時間がかからない
* 参加者が、結果を実プロダクトにも活かせそう
* 運営者が、ネタに悩まなくて済む
* 運営者が、元データを準備しやすい

これは、概ねうまく行きました。特に元データを準備しやすかったのは大きかったと思います。

### 工夫２：docker-compose で一式用意した
手元の開発環境をデータセットも含めて簡単に構築できるよう配慮しました。
弊社では商用環境を含め、基本的にはコンテナベースで設計しているため、開始15分くらいで現状の課題をホワイトボードに書いたりするチームもいました。

ざっくりの構成はこんな感じです。

```yaml

version: "3"

services:
  web:
    build: web
    container_name: web
    links:
      - mysql
    volumes:
      - ./web:/web/
    ports:
      - "8080:8080"
    environment:
      TZ: "Asia/Tokyo"
      FLASK_ENV: "development"
    command: flask run --host 0.0.0.0 --port 8080

  mysql:
    image: mysql:5.7
    container_name: mysql
    volumes:
      - ./mysql/work:/var/lib/mysql
    ports:
      - 3306:3306
    environment:
      MYSQL_DATABASE: ****
      MYSQL_ROOT_PASSWORD: ****
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci --innodb_log_file_size=512M --innodb_log_buffer_size=32M --skip_innodb_doublewrite --innodb_flush_log_at_trx_commit=2 --innodb_autoextend_increment=64
```


### 改善点１：やることがわかっていて「ただやるだけ」になるポイントは入れない
準備されたコードがイイ感じすぎると入りがスムーズに行かないのではと思い、明らかにイマイチな部分を残しました。
上記だと、uwsgiなどを用いず、Flaskの組み込みHTTPサーバーを起動しているような箇所です。

結果、やることはみんなわかっているのですが、同様の構成を作ったことがある人がいるチームとそうでないチームとの間で、時間的な差が開いてしまいました。

また、「ただやるだけの作業」に時間が割かれてしまい、各チームで創意工夫を行う時間が少なくなってしまったのは改善点でした。


### 改善点２：採点部分で盛り上げられるような工夫をする
各チームのサーバーに、並行リクエスト数を増やしながら同時に30秒程度の負荷をかけ、結果のスループットをスコアとしました。
これだと30秒後にしか結果がわからないので、もう少しリニアにグラフを見ながら楽しめる仕掛けがあったほうが盛り上がったと思います。


## まとめ

アイリッジでは、ペアプロや特定技術のハンズオンなど、様々な取り組みを行なっていますが、今回のISUCONはなかなか評判が良かったと思います。
アンケート結果などから、良かった点は以下にある様子なので、今後の催しの参考にしたいと思います。

* 少人数のチーム行う（3人くらいが良さそう）
* 勝負事にする（競い合う）