ISUCON7予選に参加しました

id:Maco_Tasu に、ISUCONに一緒に出ませんかと誘ってもらえたのでいい機会だしと思い参加しました。

LabALICEというチームで、メンバーはid:Maco_Tasu, id:karia です。

macotasu.hatenablog.jp

karia.hatenablog.jp

全員のスコアと順位を出して頂けて運営の方には感謝です。

isucon.net

最終スコアは 79,590 で、43位でした。

当日私は、画像周りの修正をしたのでそのあたりについて記録を残しておこうと思います。

事前準備

チームで3回集まって過去問を解きました。
解いた過去問は

  • isucon6予選
  • isucon4予選
  • pixiv社の社内向けisucon

です。

過去問を解くことで全体的な流れを掴むことができました。
そこで一番感じたのが、競技中にNginxの設定などを動作確認しながら作成してると時間がもったいないということでした。
NginxやMySQLなど、あらかじめ使うであろう物の設定ファイルはひな形を作っておこうとチームで話あって事前準備をしていました。

当日

最初の役割分担は id:Maco_Tasugithubへのソースコード登録、id:karia がインフラの整備となっていました。
私は、DBテーブルの確認をしてからアプリを触って動作確認をしていました。
今回のお題はチャットアプリで、画像の数が多いためNginxから返せれば速くなるのかなと思いながら触ってました。

一通りアプリを触ったので、ソースコードの確認に入りました。
ソースコードを見ると、pixiv社の社内向けisuconと同様に画像をMySQLに入れている部分が目に付きました。

予選の環境はDBサーバー1台とAPサーバー2台の構成でした。
画像はMySQLにいれるのを止めてローカルに保存してNginxから返す様にするというのはすぐに思いつきました。
問題はどのサーバーで保存するかというところで少し考えました。

  1. APサーバーからDBサーバーのMySQLに画像を保存するのを止める
  2. DBサーバーのローカルに画像を保存する

と考えたときに、DBサーバーのローカルに保存したいならDBサーバーをフロントにして、画像の保存はDBサーバーがやってそれ以外の処理は後ろのAPサーバーに流してあげれば良いんじゃないかと考えてインフラの構成を変更しました。

インフラの変更は id:karia にお願いをして、アプリの改修をしました。
改修内容は下の2つです。

  • 画像の登録/更新があったらMySQLには保存せずにローカルに保存する
  • 初期にDBに登録されている画像をローカルに書き出しておく

この後ベンチを回したりして動作を確認していたのですが、どうもDBサーバーの負荷が高くフロントと兼任させるのは良くないという事がわかってきました。
ここで、構成を変更することにしました。

次に試した方法は AP1台をフロントにして、フロント・AP・DBがそれぞれ1台づつの構成です。

  • フロントサーバーは、追加された画像のローカル保存
  • APは、画像処理以外の実行

に担当を分けてみました。

この構成だとDBに余裕ができたので、スコアを上げることができました。
その後は、GET /message GET /history/:channel_id のクエリを直したりということをしていました。

結果は予選敗退でしたが、気づきがとても多く参加して良かったと思います。
運営の皆様ありがとうございました。
id:Maco_Tasu, id:karia チームを組んでくれてありがとうございました。

学び/勘違いしていたこと

  • DBの接続設定

リクエストごとにコネクションが作られる

def db
  return @db_client if defined?(@db_client)

  @db_client = Mysql2::Client.new(

コネクションの使い回しができる

def db
  return Thread.current[:isuconp_db] if Thread.current[:isuconp_db]
  client = Mysql2::Client.new(
  • MySQLのコネクションがちゃんと閉じられていることを確認するのは大切