今年も社内 isucon を開催しました!

クリスマスも近いですね

今年1年でエンジニアとしてどれだけ成長し、強くなったかを競い合う isucon
去年に引き続き、今年も開催しました

テンプレ 2.png

【今回の参加者】

運営チーム4名、参加者26人が駆けつけてくれました。

社内エンジニア:24名
転職メンバー :6名

国籍も日本、ベトナム、中国と多岐に渡ります。

前回よりも大規模です。
前回の様子はこちら:初めて社内ISUCONを開催したらめっちゃ盛り上がった

【そもそもISUCONとは】

「お題となる Webサービスを決められたレギュレーションの中で限界まで高速化を図るチューニングバトル、それが ISUCON です。」

(ISUCON 公式サイト description より)

公式大会は年に一度、秋頃に開催されている物を社内で出来るようにアレンジして開催してみました。

【お題は ishocon2 を利用しました】

isuconを1から作成すると、4人で3ヶ月ほど掛かる巨大プロジェクトになってしまうため

LAPRASのCTOである伊藤 勝梧さん(showwinさん)が作ってくださった ishocon2 を使わせていただきました。

テンプレ 3.png

Twitter:@showwin
ishocon2のリポジトリ:https://github.com/showwin/ISHOCON2

【超丁寧なドキュメント】

ドキュメントがこれ以上ないくらい整備されていたため、運営チームで行う作業はごく僅かでした。

  • 用意されてるAMIからEC2インスタンスをチーム分用意
  • 用意されてるAMIから計測用サーバをチーム分用意
  • 独自開催用にREADMEを更新(解答リポジトリへのリンク削除など)

以上終わり、すごい、超楽。
showwinさんは神、ありがとうございます。

コードコンテストも同時開催

今回はコードコンテストも同時開催しました

コードコンテストに利用するシステムは運営メンバーのレン先生が一晩(体感)で作ってくれました(天才かな
テンプレ 4.png

爆誕した社内専用 isucon システム

問題はAtCoderを参考に作成、対応言語も8種類用意しました。

サイト制作(3週間)+問題作成(3時間×問題数)ほどの工数かかったと思います

【CodeContest 問題と正解者数】

AtCoder等のサイトから問題をお借りして、絶対に検索に引っかからないように問題をリライトしておりました、是非解答例や解説は原問をご覧ください

Grid Compression → +シロ撲滅作戦 
Lamp → +1本の松明 
Candy Distribution Again → +A - Zombie Destroy Again 
Colorful Slimes 2 → +ピクミンの理想郷 
Getting Difference → +Mission 〇〇〇〇〇〇〇〇!? 
Yes or No → +のび太くんのテスト 
Half Reflector → 魔法の筒
Triangular Relationship → +禁断の三角関係 
Together → +Let’s get together! 

サイト上ではこのように問題がよういされ、難易度に応じて点数が得られる仕組みです。

【ルール】

isuconの得点とコードコンテストの成績の両方を加味して1位が決定するため。
競技時間 7時間を4人で効率的に使い、isuconとCodeContestの両方で高得点を取らないといけません。

【同時開催した狙い】

  • 当日ISUCONの開発環境構築時に Docker Image pull で回線が混雑するため、待ち時間を有効利用
  • isuconはインフラ色が強いため、Appサイドが得意なエンジニアの活躍の場を作りたい

【コードコンテストの同時開催は最高によかった】

  • 予想通りisucon環境構築中にコードコンテストの問題を解いてくれていた。
  • Appサイドが得意なエンジニアがコードコンテストに集中出来ていた。

isuconとCode Contestの最終スコア

【isucon最終スコア】

最終スコアは3回の平均値を取りこのような結果になりました。

なんと、Eチームが計測不能、計測前の最終スコアは13788点でした。

左がisuconの時間経過ごとのスコア、右がコードコンテストのスコアになります。

ネット上では ishocon2 で25万点という猛者をみました、レベルが違いますね、すごいです。
後日CTOが家で8万点を出したようです。

【code-contest 正解者数!!】

A - Hello Lencon: 7人
A - シロ撲滅作戦" 4人
B - 1本の松明" 3人
C - 禁断の三角関係" 1人
C - Let's get together! 4人
C - Zombie Destroy Again, 4人
D - ピクミンの理想郷" 4人
D - 魔法の筒 2人
E - Mission 〇〇〇〇〇〇〇〇!? 3人
F - のび太くんのテスト 0人!!!

isuconで各チームが行った事

最後に、開催終了後に各チームで行った対策を聞いてみました。

Aチームのisucon施策

【Aチームのメンバー構成】

  • CTOのzaru@桜庭
  • 日本人:2名
  • ベトナム:1名

Aチームでやったことは明日のブログにCTOがまとめてくれました。

ざっくりまとめると

【インフラ】

  • CSS を nginx から返す
  • TCP/IP から socket 接続へ変更
  • nginx worker 数 1
  • /political_parties/:id/candidates/:id を nginx でキャッシュ
  • MySQL InnoDB memory チューニング
  • unicorn productionへ / unicorn worker数4

【アプリケーション】

  • SQL で select * from になっている箇所を必要なフィールドのみへ
  • votes テーブルへの SQL を全部 Redis へ置き換え
  • votes テーブルを抹消
  • candidates テーブルを memory エンジンへ切り替え

【コードコンテスト】

午前中は全員で isucon に集中し
午後の役割分担は、CTO桜庭以外の3人がコードコンテンストをやって
CTO自身は ISUCON のアプリケーションコード周りを担当していたようですね

その結果が上手くいったのかどうかは是非ブログをお読みください

Bチームのisucon施策

【Bチームのメンバー構成】

  • 転職メンバー:3名
  • ベトナム:1名

Bチームはゲーム開始直後、開発環境を整えながらコードコンテストに取り組み
1時間で2問を解き一気に上位に駆け上がり、終了間際まで独走状態が続いたチームでした。

【mmusasabiさん】

【isucon】

  • インデックスの部分であまり貢献できなくて辛かった。
  • 一つ一つのクエリーをexplainで見直して遅かったらチューニングしようと思った。が、わりかし早くて貢献できず
  • 最後森ちゃんのPRを正しくレビューできず無念のリバート申し訳ない!

【codeContest】

  • 最終問題難しすぎワロタ...前提となる数学知識がもっと必要そうだった
  • こだわるのをやめて、他に取り組みやすそうなものに手を出せばもっと良かったなと
  • コードの綺麗さはかなぐり捨てて答えで殴る

【saitoさん】

  • votesテーブルの構造変更 => countカラム(投票数)を追加して、insertの回数を減らした
  • candidates を on memory 化
  • UNIX DOMAIN SOCKET 対応
  • unicorn の worker数調整
  • nginx チューニング
  • muysql チューニング
  • CSSをnginxで返却

【s-moriさん】

  • 複数回呼ばれているelection_resultsを一度変数に入れて使うように変更
  • 政党得票数の初期化処理を変更
  • failureを解消(無念のリバート!)

挑戦したけどできなかったこと

  • 上位10人と最下位を取得するところでループを回さずにfirstで最初の10件とラスト1件だけ取得しようとして失敗・性別ごとの集計をごそっとやろうとして失敗

【minhさん】

コードコンテスト

  • 数学を体験して面白いです。
  • C - 禁断の三角関係は難しすぎる。

Cチームのisucon施策

【Cチームのメンバー構成】

  • 転職メンバー:2名
  • 日本人:2名

【ryosukes】

  • git pullで変更反映できるようにした
  • インデックス貼った
  • htop入れてプロセス見やすくした
  • Nginxチューニング(あまり効果なかったかも)
    • worker_process, worker_connections
    • access_log off
    • error_logは /dev/nullに捨てた
  • unicornのworker数チューニング
    • 2 → 20
    • これ以上はあまり効果が見られず
  • コードコンテストにチャレンジして一問も解けず2時間無駄にした

【chia】

  • 最初にSequel Pro使ってER図書き出そうとしたら接続できなかった
  • ほぼSQLの変更
      • でselectしてるところを必要なカラム指定に → 効果あるのか微妙(若干下がってる感じ)だったのでrevert
    • 政党得票数の集計をelection_resultsを使わず専用のクエリに書き換え
    • 1件取得で済むところはlimitつけた
    • バルクインサートやってsuccessがっつり増えたのにscore下がって諦めrevert(減点?)
  • コードコンテストは問題見ただけ
    • やろうとしたけどバルクインサート改善できそうだったので結局アプリケーションに戻った

【pepper】

isucon

  • access log profiler 入れた
    アプリケーションコードを改善するアタリをつけた
  • SQL の改善
    • 得票数のサマリ
    • 男女のサマリ
      をアプリケーションコードから sql でやるようにした
  • bulk insert にしたらスコア下がって最後まで謎だった
  • css を nginx で配信、キャッシュ、gzip

コードコンテスト

  • ピクミン一発合格して嬉しかった 500点
  • ゾンビが難しかった

【ykyk1218】

MySQLのクエリキャッシュをONにした
rack-mini-profiler入れて分析しようとしたけど、viewに影響があってベンチがこけてしまうようになるのでやめた
スロークエリ見ようと思ってログ吐き出すようにしたけど、そんなに重たいログがなかった
thread_cache_size変えた、あまり変化なし

Dチームのisucon施策

【Dチームのメンバー構成】

  • インフラの神:1名
  • 日本人:2名
  • 転職メンバー:1名

こちらのチームは、nginxからh2oへの乗り換えを検討していて非常に面白かったです。

【nob】

NGINXからH2Oへの乗り換え。
voteでtoo many file open でつまづく。
全体 8割くらい。
NGINXやMySQLのパフォーマンスチューニング。
OS ulimitなどのチューニング

【kkyouhei】

  1. 各メソッド単位での計測を行い、リスト化
  2. goのcreateVoteの複数実行ロジックを修正
  3. 各所のSQL調整
  4. mysql connection調査

【しぶさわ】

  1. 各所にインデックス作成
  2. getVoiceOfSupporterの調査

【ずいくん】

コードコンテスト全部

【わかったこと】

  • SQL のパフォーマンス改善は偉大

【改善した事】

  • インデックス貼った
  • バルクインサートに変更した
  • CSSファイルを Nginx でキャッシュした

【挑戦したけどできなかったこと】

  • Nginx から h2o に変更しようとしたけどだめだった

【スコアの変遷】

うーんずっと低空飛行だった。けど後半激上がりだった。

Eチームのisucon施策

【Eチームのメンバー構成】

  • VPoE:1名
  • 日本人:1名
  • ベトナム:1名
  • 中国:1名

【Mさん】

SQL をやりたかったですが、コードコンテストがおわらなくて、全くできませんでした!

【Rさん】

いろんな言語をそれなりに触ったほうがいいと思った。
特定の言語に特化していると、その言語の長所が活きる場面でしか活躍できない。

【CCさん】

最新バージョンのGolangをinstall
score ~11000

insert votesを改善(N query -> 1 query)
-> score ~13000

political_parties/:nameを改善
indexを追加
-> score ~14000

nginxのcacheを運用
-> score ~24000
{"score": 24332, "success": 19516, "failure": 0}

votesのデータベース構造を改善
-> score ~50000(見積もり)
-> benchmarkツール壊れました

Fチームのisucon施策

【Fチームのメンバー構成】

  • インフラの守り神@loveliver:1名
  • 日本人:1名
  • ベトナム人:2名
  • 【ビジネスチーム】プログラミング勉強中@ぴろり :1名

Fチームには何と、普段ビジネスチームで働いているぴろりさんが参戦してます。

100日以上プログラミングを勉強し、エンジニアのアウトプットチャンネルに知見を長文投稿しまくってるその姿勢に感動し、isuconに初参戦しました、すごい!

【導入したツール】

  • Docker(ぴろり)
  • rack-mini-profiler
  • Datadog(306)
  • alp

【わかったこと】

  • GoはRubyとは違ってbuildが必要なこと
  • go build -o webapp *.go
  • ActiveRecord は神
  • コマンドでGitを使ってPull Requestをするまでのやり方
  • SQL文の改善
  • SELECTでカラムを取得してくる際、*ですべて取ってくるのではなく必要なカラムを限定すれば無駄なSQL操作が減る
  • インデックスを貼れば検索速度が改善される
  • init.sql を編集(できなかった)
  • ローカルでマトリックスの仕組みが深く理解出来ました。

【改善したこと】

  • Nginx
  • gzip 圧縮
  • css を静的に返した
  • /candidates をcacheさせた(効果は不明)
  • tcp から socket 通信
  • Unicorn
  • worker_processの数をいじった
  • socket 通信した

【MySQL】

  • ログをは吐き出すように
  • 標準、エラー、スロークエリー
  • Datadog にログ転送
  • クエリキャッシュ有効化
  • パラメータチューニング
  • インデックスを張った(効果は謎)

【Ruby】

  • SELECTで取ってくるカラムの限定

【挑戦したけどできなかったこと】

  • GOでサーバー立ちあがなかった
  • Permutation with Replacementで試してましたが、実行時間がすごく長いので、C - 禁断の三角関係の問題まだクリア出来ません。
  • 最初はPython 3でコードを書きましたが動かなかった(Python 2しか対応してないから)。
  • SQLにインデックスを貼る
  • Datadog入れたけど解析できないので、 New Relic でも入れたほうがいいかもです

【スコアの変遷】

  • -490000(初期スコア)
  • 2000 (Nginx チューニング)
  • 6000 (worker_process 増やした?)
  • 10000(css 静的化)
  • 16000(mysql クエリキャッシュ)
  • 17000(datadog 外した)
  • 18000(Ruby やめて なにもいじってない python にした)

コードコンテスト: 1150点!

isucon + code contestを開催してみて

運営準備は ishocon2 がなかったら本当にやばかったです。
showwinさんに重ねてお礼を申し上げます。

また一緒にisucon開催に向けて準備してくれた3人のメンバーにも感謝です、ありがとうございました。

大変ではありましたが、得意、不得意な部分がよくわかる競技ですし、発見も色々あったと言っていただけたので今年も開催してよかったなと思っております。