ISUCON公式Blog

WINNER'S PRIZE \1,000,000

  
      
  
   

オンライン予選

   

2022年7月23日(土) 10:00-18:00

   

オンライン本選

   

2022年8月27日(土) 10:00-18:00

  
  
ISUCONの過去問に
チャレンジするための
シンプルな環境構築
商標「ISUCON」利用の
ガイドラインはこちら

ISUCON10 本選の結果発表と全チームのスコアに選手の皆さまより指摘があり、誤りが確認されたため下記の通り発表いたします。

ISUCON10 本選当日マニュアルでは、最終スコアは競技終了後に運営が実施する 3 回の負荷走行のうち最も高いものと定義していました。その定義に従い、各チーム 3 回の負荷走行を追試として実施しましたが、その最大を計算する際に 1 回目の負荷走行のスコアについて計算に加えられておらず、誤って競技終了時点で最後に実施された負荷走行のスコアが、追試 1回目のスコアとして計算に加えられていました。

正しい順位について

誤りを訂正するため、改めて計算および複数人での検算をしたところ、下記のチームについて順位に誤りがあることがわかりました。
(当初発表していた順位 → 正しい順位)

  • 11位 → 8位: hidekiy (最終スコア: 24123 → 28244)
  • 8位 → 9位: shallowverse (最終スコア: 26249)
  • 9位 → 10位: ふんばり温泉チーム (最終スコア: 25080)
  • 10位 → 11位: 101010 (最終スコア: 24682 → 24870)
  • 16位 → 15位: SNE (最終スコア: 15706 → 14494)
  • 17位 → 16位: :innocent::innocent::innocent: (最終スコア: 14206)
  • 19位 → 17位: FCCPC_かみのやま温泉 (最終スコア: 12365 → 10751)
  • 20位 → 18位: いすこんがさき、しゅうろんはあと (最終スコア: 10177)
  • 15位 → 19位: curl gotti (最終スコア: 15909 → 7747)
  • 18位 → 20位: 牡蠣の鋭利な殻が指に突き刺さり利き手を負傷 (最終スコア: 12550 → 6805)
  • 22位 → 21位: へしこず (最終スコア: 4803 → 5707)
  • 21位 → 22位: SunPro (7633 → 2691)

  • なお、1 位~ 7 位に関して変動はありませんでした。

    スポンサー特別賞について

    今回の順位訂正に伴い、スポンサー各賞の対象チームに変化が生じることが分かりました。下記のように対応いたしますので、ご確認ください。
    • LegalForce 記念ラッキー賞 (株式会社 LegalForce 様)
      • 総合 10 位に対して贈られる賞です。
      • 当初発表していたチームは「101010」でしたが、順位の変動により、「ふんばり温泉チーム」が受賞者となります。
      • チーム「101010」については同等の特典を主催である LINE 株式会社より手配いたします。

    • またあいま賞 (LINE 株式会社)
      • fail (0 点の記録) していない下位 5 チームに対して贈られる賞です。
      • 当初発表していた受賞チームは「FCCPC_かみのやま温泉」「いすこんがさき、しゅうろんはあと」「牡蠣の鋭利な殻が指に突き刺さり利き手を負傷」「へしこず」「SunPro」の 5 チームでしたが、新たに「curl gotti」を加えた 6 チームを受賞者といたしました。

    訂正後の順位、最終スコアデータについて

    下記の通りとなります。

    49545 takonomura (学生)
    43366 Azeit (学生)
    34767 がんもどき (学生)
    31432 一口坂46
    30834 百万円ドリブン
    30766 FetchDecodeExecWrite
    28628 ヌルポインターマリアユニバース
    28244 hidekiy
    26249 shallowverse (学生)
    25080 ふんばり温泉チーム
    24870 101010
    23438 MN
    23294 hoge
    16321 BruteForce (学生)
    14494 SNE
    14206 😇😇😇 (学生)
    10751 FCCPC_かみのやま温泉
    10177 いすこんがさき、しゅうろんはあと (学生)
    7747 curl gotti
    6805 牡蠣の鋭利な殻が指に突き刺さり利き手を負傷
    5707 へしこず
    2691 SunPro

    順位が変動していないチームについては個別に言及しません。ただし、チーム「百万円ドリブン」に関しては本件とは別の集計ミスにより前回発表の最終スコアが誤っていました。正しい最終スコアは 30834 であり、そのように訂正されています。この修正によるチーム「百万円ドリブン」の順位変動はありませんでした。

    並行チームの最終スコアデータについて

    並行チームの最終スコアデータについても、同様の誤りがあったため下記の通り訂正します。

    (39689) fujiwara組
    (11113) 鍋部(2人前)
    (5784) 失敗から学ぶISUCONの正しい歩き方 the Revenge
    (0) NaruseJun

    ただし、前回発表したとおり「NaruseJun」と「失敗から学ぶISUCONの正しい歩き方 the Revenge」は失格相当となります。

    発生原因について

    ISUCON10 運営チームでは、スコア発表にあたりミスを防ぐため、複数の方法にてデータの抽出と計算を行い、その結果を突合することで検算を実施していました。今回のミスについては、追試 1 回目のデータの抽出のみ誤りを見逃しており、誤ったデータをその後の過程で利用してしまったことが原因です。

    なお、今回追試の負荷走行を 3 度実施するルールにした背景として、アプリケーションが時刻 (時計) を利用する箇所があったため、ベンチマーカーと時刻のズレで fail が発生してしまう可能性があったことが挙げられます。もちろん、競技時間中にそれが発生しないよう、最大限ベンチマーカー側で考慮する実装にはなっていましたが、偶発的な失格の可能性を少しでも減らすため、このような方式を採りました。

    COVID-19 に伴うオンライン開催から、本選ライブ企画といった新しい試みをしていて、リアルタイムなライブでの結果発表が控えていること、また、これまでの開催では見られなかった複雑な最終スコアの採用方法などで事故が発生しやすい状況だったと考えられます。次に ISUCON が開催される際は、予選での経験も含め、ISUCON10 運営チームとしてその反省点を引き継いでいきたいと考えています。
    Read more...

    ISUCON10 オンライン本選の利用言語比率を公開します。オンライン本選は33チームの参加がありました。

    オンライン本選 利用言語比率

    利用率の全体ランキングは以下の通りです。

    Go     28組 84.8%
    Nodejs   3組  9.1%
    Ruby     1組  3.0%
    Rust     1組  3.0%

    優勝したtakonomuraチームの利用言語はGoでした。

    昨年の言語比率はこちら
    Read more...

    2020.10.6 18:18 更新 ConoHa学生応援賞を訂正
    2020.10.5 18:22 更新
    スコアデータに誤りがありましたので訂正いたしました、詳細は本選スコアデータおよび順位の誤りについてをご確認ください
    ---
    ISUCON10 に参加いただいた皆さん、ありがとうございました!
    10月3日に開催された ISUCON10 本選の結果発表および、本選出場全チームの最終スコアについてご案内します。

    受賞者の発表

    ISUCON10 主催の LINE 株式会社より、本選の総合1〜3位のチーム、学生1〜2位のチームに対する賞、および特定スコアに対して特別賞を用意していました。DSC06477

  • 総合1位: 賞金 100 万円
  • 総合2位: 賞金 30 万円
  • 総合3位: 賞金 10 万円
  • 学生1位: 賞金 30 万円
  • 学生2位: 賞金 10 万円
  • 特別賞: 賞金 5 万円


  • 以下のとおり、各賞の受賞チームを発表します。

    総合1位および学生1位

  • takonomura (学生)48,344 点


  • 総合2位および学生2位

  • Azeit (学生) 43,366 点


  • 総合3位

  • がんもどき (学生) 34,767 点


  • 特別賞

    最初に 20,000 点を越えたチーム
  • 第5西東京市 (12:26 時点で 20,113 点を達成)


  • スポンサー特別賞

    また、スポンサー企業各社からスポンサー特別賞(順不同)をご用意いただきました。スポンサー企業の皆様に感謝申し上げます。以下に受賞チームを記載します。

    株式会社サイバーエージェント様より「サイバーエージェント賞」

    総合1位〜3位、及び学生1位の参加者
    (1人2個*3で1チームに6個ご用意、総合順位と学生1位が重複した場合は2セット進呈いたします)
    slack-imgs
  • takonomura (学生)
  • Azeit (学生)
  • がんもどき (学生)


  • 株式会社エイチーム様より「ええチーム賞」

    20,229 点に最も近いチーム
    (1人1個、進呈いたします)
    DSC06472
  • hoge (23,294 点)


  • LINE 株式会社より「またあいま賞」

    (1人1個、進呈いたします)
    DSC06473
    ランキングの下位56チーム
  • curl gotti
  • 牡蠣の鋭利な殻が指に突き刺さり利き手を負傷
  • FCCPC_かみのやま温泉
  • いすこんがさき、しゅうろんはあと (学生)
  • SunPro
  • へしこず


  • 株式会社 LegalForce 様より「LegalForce 記念ラッキー賞」

    総合10位のチームに、高級キーボード
    (1人1個、進呈いたします)
  • ふんばり温泉チーム

  • ※訂正スコア対応のため同等の賞を準備予定でしたが受賞チームから辞退の連絡があったため修正

    宇宙海賊合同会社様より「宇宙海賊賞」

    最初に 28,400 点、40,300 点、60,100 点を越えたチーム
    (1人1個、進呈いたします)
    DSC06471
  • ウー馬場ーイーツ (14:37 時点で 30,800 点を達成)
  • Azeit (学生)(17:12 時点で 40,677 点を達成)


  • KLab 株式会社様より「KLab 賞」

    KLab 賞1: 他社受賞対象をのぞいて最も順位の高かったチーム
    (1人1個、進呈いたします)
    DSC06474
  • 一口坂46


  • KLab 賞2: 他社ならびに既出のKLab賞対象をのぞいて最も順位の高かった学生チーム
    お好きな書籍1万円分購入権
    (1人1権利として、進呈いたします)
  • shallowverse (学生)


  • ConoHa学生応援賞

    学生1・2・3位に賞品(ConoHaカード)
    (1人1セット、進呈いたします)
    ※当初、総合順位への進呈も記載しておりましたが訂正いたします
    conoha
    • 学生1位へ 5万円分のConoHaカード
      • takonomura (学生)
    • 学生2位へ 2万円分のConoHaカード×3名
      • Azeit (学生)
    • 学生3位へ 1万円分のConoHaカード×3名
      • がんもどき (学生)

    最終スコアについて

    参考として、賞の判断基準となった各チームの最終スコアについて説明します。

    最終スコア算出手順

    本選の最終スコアは、ISUCON10 本選当日マニュアルに従い、以下の方法で算出を行いました(下記は説明のためマニュアルから一部表現は変えています)

    1. 全チームのサーバーを再起動し、10 分以上待つ
    2. 全チームのベンチマークを運営より実行
      • 計測は各チーム 3 回ずつ実施する。
    3. (2) で実施した最後の負荷走行が fail となっているチームに関しては、再度計測を実施する
      • この際、再度 fail となったチームは失格とする。
      • これは、負荷走行を pass した直後の状態で (4) の「再起動・ブラウザ動作確認」を行うことを目的とした手順です。
    4. 全チームのサーバーを (1) と同手順で再起動し、ブラウザから動作確認を行う
      • ここで正常な動作が確認できなかったチームは失格とする。
    5. (2) の負荷走行で計測したスコアのうち、その中で最も高いスコアをそのチームの最終スコアとする
      • fail については 0 点と数える。


    最終スコア

    最終スコア算出手順をすべて通過したチームとそのスコアは以下の通りです。
    なお、当初発表したスコアデータには誤りがありましたので訂正いたしました、詳細は本選スコアデータおよび順位の誤りについてをご確認ください

    49545 takonomura (学生)
    43366 Azeit (学生)
    34767 がんもどき (学生)
    31432 一口坂46
    30834 百万円ドリブン
    30766 FetchDecodeExecWrite
    28628 ヌルポインターマリアユニバース
    28244 hidekiy
    26249 shallowverse (学生)
    25080 ふんばり温泉チーム
    24870 101010
    23438 MN
    23294 hoge
    16321 BruteForce (学生)
    14494 SNE
    14206 😇😇😇 (学生)
    10751 FCCPC_かみのやま温泉
    10177 いすこんがさき、しゅうろんはあと (学生)
    7747 curl gotti
    6805 牡蠣の鋭利な殻が指に突き刺さり利き手を負傷
    5707 へしこず
    2691 SunPro

    失格チーム(ブラウザ動作確認失敗)

    以下のチームは、最終提出スコア算出手順 (4) における、運営スタッフによるブラウザからの動作確認において、正常な動作が確認できなかったため失格となりました。下記は参考値として手順 (2) における最高スコアを括弧内に記載しています。

    (11411) 勉強不足の分は有り余る才能でカバーしようかなと思っております
    (4498) アサシン

    失格チーム(規定の負荷走行が fail)

    以下のチームは、最終提出スコア算出手順 (2) における3回目の負荷走行が fail となり、また (3) で規定された再度の負荷走行も fail していたため、失格となりました。下記は参考値として手順 (2) における最高スコアを括弧内に記載しています。

    (43249) ウー馬場ーイーツ
    (42106) 計算機科学実験及演習5 (学生)
    (36664) メンチカツ
    (31127) チーム中目黒乗り過ごし
    (14765) ワンランク上のジロリアン (学生)
    (0) はしもとせいこ
    (0) ニル侍
    (0) 第5西東京市
    (0) カレーおじさん

    本選当日における「並行チーム」のスコア

    本選当日には、予選敗退チームの中から4チームにご協力をお願いし、「並行チーム」として本選問題に取り組んでいただいたり、インタビューに出演したいただいたりと、ライブ配信を大いに盛り上げてくださいました。並行チームの皆様、ご協力どうもありがとうございました。

    以下、並行チームの最終スコアを参考値として括弧内に記載しています。

    (39689) fujiwara組
    (11113) 鍋部(2人前)
    (5784) 失敗から学ぶISUCONの正しい歩き方 the Revenge
    (0) NaruseJun

    ただし、NaruseJun は規定の負荷走行 (3) が fail であり、また 失敗から学ぶISUCONの正しい歩き方 the Revenge はブラウザ動作確認 (4) に失敗したため、両チームは ISUCON10 本選当日マニュアルの規定上は失格相当となります。


    当日の運営・配信会場の様子


    参加者の皆さんはオンラインの参加でしたが、運営チームと並行チームはこういった雰囲気で配信をしておりました。
    DSC06486
    DSC06490
    DSC06500
    DSC06516
    DSC06501
    DSC06512
    DSC06517
    DSC06519
    DSC06520
    DSC06522
    DSC06528
    DSC06533
    DSC06543
    DSC06550
    DSC06553
    DSC06555
    DSC06571
    DSC06587
    DSC06597
    DSC06621
    DSC06626
    DSC06661
    DSC06662
    DSC06686
    DSC06687
    DSC06695
    DSC06705
    DSC06713
    DSC06734
    DSC06756
    DSC06763
    DSC06765


    以上です、ご参加いただいた皆さんありがとうございました!
    DSC06783

    Read more...

    ISUCON 10 予選問題作問担当の @yosuke_furukawa です。ISUCON 10 の予選お疲れさまでした。このブログでは、 ISUCON 10 の予選問題の解説と講評を行います。

    問題については下記のURLにて公開されています。
    http://github.com/isucon/isucon10-qualify

    動作確認をしたい場合は README.md を確認の上、検証してみてください。

    課題アプリケーション ISUUMO について

    ISUCON10 の予選の問題は、 ISUUMO と呼ばれるイスに合う物件を検索するサイトでした。せっかくリクルートが作問担当になったので、リクルートならではのものにしたいのと、ずっと社内ISUCONでポリシーとして持っていた「実際に起きているパフォーマンス問題に近い課題を設定したい」という思いから作りました。
    pasted image 0
    ISUUMO トップ画面



    リクルートらしさを出そうということで、実際に社内で開発している SUUMO を元にしました。 Bot からのリクエストが多かったり、「なぞって検索機能」があるのは実際の状況・機能を元にしています。
    pasted image 1
    なぞって検索画面



    フロントエンドは Next.js で構築し、予め静的ページとしてビルドしています。なぞって画面に Leaflet と呼ばれる地図用ライブラリを使ったり、 なぞった領域の凸包を取るために、 monotone-convex-hull-2d と呼ばれるライブラリを使ったりとかなり工夫しています。興味あればご一読ください。実際にはフロントエンドはチューニング対象ではなく、 実際のリクエストがどう使われてるかを確認するためと、再起動試験時にAPIの整合性の確認をするために使われています。

    解説

    今回の問題は位置情報を使ったものであり、参加者の皆様にとってはあまり馴染みのないものであったのではないかと思います。いくつかこちらが回答した内容を元に、用意したチューニングポイントについて解説します。

    ちなみに予選作問チームの一人がリハーサルで実施した際の最高点数は 8000 点程度でした

    安い椅子と物件を検索するAPI(low_priced)にindexが効いてない

    トップページにある安い椅子と物件を検索する API があり、そこの SQL に index が効いてません。実際に計測すると、本APIへのリクエスト数が多く Query が遅いことがわかります。
    SELECT * FROM chair WHERE stock > 0 ORDER BY price ASC, id ASC LIMIT ?
    SELECT * FROM estate ORDER BY rent ASC, id ASC LIMIT ?
    ORDER BY を狙って index を貼らないとスコアが上がりにくくなっています。特に初期段階ではベンチマーカーは椅子と物件の検索しかしません。ここをまずは対処する必要があります。

    椅子、物件検索 API に index が効いてない

    椅子と物件を検索する際に、毎回 popularity が降順 (DESC) であり、 ID の昇順 (ASC) で検索をしています。降順と昇順が組み合わさった ORDER BY は デフォルトでインストールされてる MySQL 5.7 では単純に index を貼っても効きません

    SELECT * FROM estate WHERE latitude <= ? AND latitude >= ? AND longitude <= ? AND longitude >= ? ORDER BY popularity DESC, id ASC

    降順の index を効かせたかったのと位置情報の検索を見て、 MySQL 8 に上げた人たちも多かったです。

    MySQL 8 にしても良いのですが、単純に実施してしまうと 設定の違いにより、パフォーマンスが劣化することもあります。現実に運営側の事前検証ではそこまで点数が上がりませんでした。

    popularity は単純にマイナスをつければ昇順に変更できるので想定回答としては負の値をinitialize で入れてしまうか、 MySQL の generated columns を使って 負の値を持った popularity を作ってそこに入れるというのを想定していました。

    CREATE TABLE isuumo.estate
    (
    id INTEGER NOT NULL PRIMARY KEY,
    name VARCHAR(64) NOT NULL,
    description VARCHAR(4096) NOT NULL,
    thumbnail VARCHAR(128) NOT NULL,
    address VARCHAR(128) NOT NULL,
    latitude DOUBLE PRECISION NOT NULL,
    longitude DOUBLE PRECISION NOT NULL,
    rent INTEGER NOT NULL,
    door_height INTEGER NOT NULL,
    door_width INTEGER NOT NULL,
    features VARCHAR(64) NOT NULL,
    popularity INTEGER NOT NULL,
    popularity_desc INTEGER AS (-popularity) NOT NULL # generated column でカラムを追加する
    );

    ALTER TABLE estate ADD INDEX estate_popularity_id_idx(popularity_desc, id); # popularity_desc にインデックスを貼る


    この辺りの ORDER BY を狙って index を貼れるかどうかが最初のポイントでした。ここを抜けるとベンチマーカーからの負荷の掛け方が変化し、なぞって検索や CSV 入稿といった処理が増え、データの量も増えていきます。また、 Bot からのリクエストも増えていきます。

    なぞって検索に N+1 がある

    なぞって検索の API の内部を詳しく見ると「なぞった範囲の緯度経度の最小値と最大値を取り、一度検索し、 検索にヒットしたものの中で与えられた多角形の範囲内にあるか」を一つずつ確かめている箇所があります。

    この部分は所謂 N+1 処理になっています。「多角形の範囲内にあるか」に関しては少し工夫すれば SQL で一度の処理で絞り込めます

    緯度経度を POINT 型にして一つにまとめたカラムを事前に用意しておいた上で、 ST_Contains を使って検索すれば一度の検索で多角形の中にある物件を検索できます。

    ST_Contains は空間インデックスを使う時に一度、最小外接矩形 (MBR) を使ってオブジェクトを絞り込みます。最小外接矩形 (MBR) の絞り込みは前述の「緯度経度の最小値と最大値を取ってフィルタする処理」に該当します。空間インデックスを使うと前段で絞り込みをやる必要がなくなり、 N+1 も解消することが可能です。

    point       POINT AS (POINT(latitude, longitude)) STORED NOT NULL
    SELECT * FROM estate WHERE ST_Contains(ST_PolygonFromText(%s), point) ORDER BY popularity_desc, id LIMIT ?

    さらにこの処理をする上で SPATIAL INDEX を貼れば上記のSQLにも index が効くようになります。※ MySQL 5.7 では Generated Columns に SPATIAL INDEX を貼る場合は STORED にしなければいけません。
    ALTER TABLE estate ADD SPATIAL INDEX estate_point_idx(point);
    なぞって検索の処理をどうやって効率化するかは各チームで対応が異なった部分でした。SQLで一度で取るのではなく、アプリケーション側で多角形内にあるかを検証するチームも多かったです。

    予選突破した上位陣のブログを読むと、なぞって検索の効率化に早めに着手し解決できているチームが多く、予選通過のキーポイントになっていると感じました。

    bot によるリクエストがある

    この部分も本家の SUUMO 由来の処理です。 bot からリクエストが来ることが多く、実際には bot のリクエストは椅子購入や物件資料請求といったコンバージョンにつながらないので、503エラーで弾いても問題ないことが当日のマニュアルに記載されています

    https://gist.github.com/progfay/25edb2a9ede4ca478cb3e2422f1f12f6#bot-%E3%81%8B%E3%82%89%E3%81%AE%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88
    /ISUCONbot(-Mobile)?/
    /ISUCONbot-Image\//
    /Mediapartners-ISUCON/
    /ISUCONCoffee/
    /ISUCONFeedSeeker(Beta)?/
    /crawler \(https:\/\/isucon\.invalid\/(support\/faq\/|help\/jp\/)/
    /isubot/
    /Isupider/
    /Isupider(-image)?\+/
    /(bot|crawler|spider)(?:[-_ .\/;@()]|$)/i

    上記の正規表現で Bot からのリクエストかどうかを検出することが可能です。 検出したら 503 のステータスコードで返せば Bot に邪魔されなくなります。

    この部分は単に実装されてないだけなので、実装すればある程度の効果を生みます。マニュアルを良く読めば書いてあるので、マニュアルをきちんと読んでいるかがポイントでした。

    アプリケーションのミドルウェアで実装するのを想定していましたが、手前においた nginx 部分で対処するチームも一定数いました。どちらで制御しても構いません。言語ごとの正規表現エンジンの実装の差異によって有利不利が働く可能性もありましたが、どちらにせよ大差はなさそうでした。

    また、「開始してすぐに実装したものの、スコアに大きな変更がなかった」という旨のエントリを書いている参加者がいましたが、実はベンチマーカーは初期の時点では Bot からのリクエストをほとんど送りません。なぞって検索や椅子、物件の検索が効率化されて負荷レベルが上がってくるとやっと送るようになります。

    マニュアルに記載があるからと言って闇雲に実装をするのではなく、ある程度負荷の状況を見ながら優先順位をつけて対処策を実装する必要があります。

    estate と chair で DB を別サーバに分ける

    DB をテーブルごとに別サーバに分けるのも効果的です。特に chair テーブルと estate テーブル間に JOIN が存在しないため、2つのデータベースに分割して、検索処理を分散させることが可能です。
    pasted image 2
    App / DB x 2 で3台構成を組む例



    今回の問題は DB の CPU が100%に張り付くケースが多いです。しかも1台分のスペックはそこまで強くありません。3台構成の際に App x2 / DB x1 にするのではなく、 App x1 / DB x2 にすることで負荷分散ができます。

    検索条件にも Index を貼る

    椅子や物件の検索条件はユーザーからの指定に従って検索条件が複雑に変わる仕様でした。

    そのため rent や price, height といった条件でも検索に来ることがあります。さらに slow-query のログを詳細に読むと、検索条件にも index が効いておらず、遅いことを示すログが出ています。

    pt-query-digest などのクエリ解析ツールを使って遅いクエリを特定すること、それに従って検索条件にも index を貼った方が効果的です。
    ALTER TABLE chair ADD INDEX chair_price_idx(price, stock);
    ALTER TABLE chair ADD INDEX chair_height_idx(height, stock);
    ALTER TABLE chair ADD INDEX chair_kind_idx(kind, stock);

    ALTER TABLE estate ADD INDEX estate_rent_door_width_idx(rent, door_width);
    ALTER TABLE estate ADD INDEX estate_rent_door_height_idx(rent, door_height);

    実はベンチマーカーは price と rent に検索条件が多めに実施してくるように設計してあります。この辺りもアクセスログ、クエリーログをきちんと確認できていたかを問う箇所でした。

    ログを出すのを止める

    アプリケーション側で SQL やリクエストの内容をロギングしている箇所があります。通常時にはログは出すべきですが、高負荷時にはそこも問題になり得るので、ログをオフにしておく対応をすると多少効果があります。

    ちなみに Go の場合 echo というフレームワークを使っています。echo のログが初期に設定されている debug モードだと整形された JSON がログに出力されます。この部分が高負荷状況では特に問題になります。

    Bulk Insert を行う

    CSV入稿時に1件ずつ INSERT している箇所があります、csvファイルにはデータが1000行存在するため、1000回 INSERTする事になります。 まとめて一気に INSERT する方が良いでしょう。

    1000回程度の INSERT なら、さほど効果がないように見えますが、負荷が上がる終盤にこの対応をしていないと CSV 入稿時にタイムアウトする確率が上がります。 CSV 入稿はタイムアウトであっても失敗した場合は即 Fail 扱いになるので、対処しておかなければ失格になる可能性が上がります

    その他のチューニングポイントとなり得る箇所

    上述した対応を運営側では行い、 8000 点台を記録する事ができました。ただし、この他にもいくつかチューニングできるポイントはあります。以下はブログを読んだ中にあったチューニングのアイデアを抜粋させていただいてます。

  • SELECT FOR UPDATE をやめて、 UPDATE と affected_rows の処理にし、ロックの時間を減らす。
  • OR検索を UNION ALL に変更し、 index が効くようにする。
  • API のレスポンス値をアプリケーションサーバのインメモリにキャッシュし、メモリから返すようにする。

  • すべての処理を適用した際にどこまで点数が上がるのかは運営でもまだ未検証です。

    講評

    皆様お疲れさまでした。
    運営側で参加者のブログを確認していると、やはり「なぞって検索を効率化できたかどうか」、「AppとDBサーバの分割を適切にできているか」が予選通過のターニングポイントのように感じています。
    なぞって検索は敢えて処理が複雑に作られており、読み解くことも中でやってる処理を改善することも難しく感じるように設計されています。

    また、3台構成の設計も従来の常識にとらわれずにリソースの状況とアプリケーションのコード内容から DB を分けるという設計ができるのかがポイントでした。

    尻込みせずになぞって検索の高速化に挑戦し、常識にとらわれずに3台構成の設計ができたチームが突破をしていました。実力とチャレンジスピリットの両方が備わったチームがきちんと突破できていると思います。

    謝辞

    問題の作問やりませんか?と声をかけてくれた 941 さんをはじめ、会場を提供し、夜遅くまで残って会場の整備をしてくれた LINE 社の皆様、本選の問題が忙しいにもかかわらず予選問題の回答とフィードバックをくれた 白金動物園の皆様、直前のインフラ構築で忙しいながらもギリギリまで不具合や障害の解決に付き合っていただいた CyberAgent 社の皆様、誠にありがとうございました。

    最後に非常に拙い運営になってしまいご迷惑をおかけしましたが、最後まで付き合っていただいた参加者の皆様、ありがとうございました。

    Read more...

    2020.09.23 20:15 本選出場チームに変更があったので内容を更新
    --
    ISUCON10 オンライン予選の利用言語比率を公開します。オンライン予選は490チームの参加があり、運営で把握ができたのは468チームとなりました。

    オンライン予選 利用言語比率

    利用率の全体ランキングは以下の通りです。

    Go      276組 59.0%
    Ruby     81組  17.3%
    Python   47組  10.0%
    Nodejs   29組  6.2%
    PHP     18組  3.8%
    Rust      8組  1.7%
    Perl       7組  1.5%
    Elixir     1組  0.2%
    original-ruby 1組  0.2%


    本選出場が決まった33チームに限定すると以下となります。

    Go    28組  84.8%
    Nodejs  2組   6.1%
    Rust    1組  3.0%
    Ruby   1組  3.0%
    PHP    1組  3.0%    

    昨年の言語比率はこちら
    Read more...

    ↑このページのトップヘ