Skip to content

Instantly share code, notes, and snippets.

@mackee

mackee/manual.md Secret

Last active July 23, 2022 13:45
Show Gist options
  • Save mackee/4320c18919c8f6f1867849378a17e651 to your computer and use it in GitHub Desktop.
Save mackee/4320c18919c8f6f1867849378a17e651 to your computer and use it in GitHub Desktop.
ISUCON12 予選当日マニュアル

ISUCON12 予選当日マニュアル

スケジュール

  • 10:00 競技開始
  • 17:00 リーダーボードの更新停止
  • 18:00 競技終了
  • 翌 14:00 結果発表

アプリケーション ISUPORTSについて

ISUPORTSの仕様についてはISUPORTSアプリケーションマニュアルを参照してください。

ISUCON12 ポータルサイト(ポータル)

ISUCON12 の競技では下記のウェブサイトを利用します。事前に登録した情報を用いてログインしてください。 なお、このページは競技開始時刻までアクセスすることはできません。

https://portal.isucon.net/contestant

ポータルでは、負荷走行(ベンチマーク)の実行/結果確認、質問/サポート依頼の送信、リーダーボードの確認ができます。

リーダーボードの更新について

ポータル上のリーダーボードは、競技終了 1 時間前に他チームの情報が更新されなくなり、自チームの情報のみ更新されます。

Discord の利用について

ISUCON12 サポート Discord サーバーは競技中ならびにその前後の時間はすべてのチャンネルが発言不可となります。 競技時間中はポータルを通して質問/サポート依頼を送信することができますので、そちらを利用してください。

ただし、予選参加者(以下選手)は競技時間中も Discord の確認が可能な状態、通知が受け取れる状態を維持してください。 これは主催者が選手とリアルタイムでのチャットが必要だと判断した場合、主催者が Discord 上でプライベートチャンネルを作成しメンションの上、呼びかけを行う場合があるためです。呼びかけに応じない場合、競技に支障をきたす可能性があるため、必ず応答可能な状態を維持してください。

また、主催者からのアナウンス等も Discord で実施されます。

質問について

選手は主催者へ質問を送信することができます。質問は競技内容・マニュアル・レギュレーション等に対する疑問点の確認や、サーバー障害などのトラブル報告・サポート依頼に利用することができますが、これに限りません。

主催者は質問された内容が競技の一環である場合は、回答できない旨を返答することがあります。

競技時間中の質問について、主催者からの回答は全選手へ公開、あるいは個別に回答されます。全選手へ公開される場合、質問内容の原文、あるいは主催者による内容の要約が公開されます。未回答の質問・未公開の回答については質問した選手およびそのチームメンバー、主催者のみが確認できます。質問への回答・更新はポータル上にて選手およびそのチームへ通知されます。

主催者は競技時間中の質問への回答を、原則として全選手へ公開します。ただし、重複する質問や、選手およびチーム個別の問題に対する対応の場合、この限りではありません。

サポート対象外の事項

主催者が事前に Discord サーバー等で告知していた通り、下記はサポート対象外となります。

競技環境確認を事前に行っていないチームからの競技環境に関する質問/サポート依頼

  • AWS クーポンに関する質問/サポート依頼
  • スポンサー各社が提供しているサービスについての質問/サポート依頼

競技環境構築と接続

競技に参加するにあたり、各チームが用意した AWS アカウントで競技環境を下記の手順に従って構築してください。

1. テンプレートのダウンロード

まず、環境構築には AWS CloudFormation を利用するため、チームはポータル上から AWS CloudFormation のテンプレートをダウンロードします。 テンプレートはチームごとに固有のものとなっているため共有厳禁です。

https://portal.isucon.net/contestant/contestant_instances

このテンプレートでは以下のリソースを作成します。

  • EC2 インスタンス (c5.large)x 3
  • EBS(gp3 20GB)x 3
  • EIP x 3
  • VPC x 1
  • VPC サブネット x 1
  • VPC ルートテーブル x 1
  • インターネットゲートウェイ x 1
  • セキュリティグループ x 1
  • Availability Zone 情報取得に利用する Lambda 関数 x 1
  • IAM ロール x 2
  • EC2 インスタンスプロファイル x 1

テンプレートから作成される IAM ロールは、EC2 インスタンスおよび Lambda 関数で上記リソースの情報取得を行うために利用します。 許可されているアクションは AWS の仕様上、アカウントに存在する他のリソースの情報も閲覧できる設定になっていますが、主催者は不要な情報の取得は行いません。

2. スタックの作成

  1. AWS マネジメントコンソールの CloudFormation を開き、ページ右上に表示されているリージョン名がアジアパシフィック(東京)(ap-northeast-1)になっていることを確認します。
  2. 「スタックの作成」をクリックします。 既存のスタックがある場合は「スタックの作成」から「新しいリソースを使用(標準)」を選択します。
  3. 「スタックの作成」ページから「テンプレートの準備完了」、「テンプレートファイルのアップロード」を選択し、上記でダウンロードしたテンプレートのアップロードを行い「次へ」をクリックします。
  4. 「ステップ 2 スタックの詳細を指定」では任意のスタック名を設定し、「次へ」をクリックします。
  5. 「ステップ 3 スタックオプションの設定」では変更を行わず「次へ」をクリックします。
  6. 「ステップ 4 レビュー」において、ページ最下部「スタックの作成」ボタンの上に表示されている「AWS CloudFormation によって IAM リソースが作成される場合があることを承認します」にチェックを入れた上で、「スタックの作成」をクリックします。
  7. 作成したスタックの状態が CREATE_COMPLETE(作成完了)になるまで待機します。

3. サーバーへの SSH 接続

スタックの作成完了後、1 分程度で SSH 接続できるようになります。サーバーには選手が GitHub に登録している SSH 鍵を利用して、ユーザ名 isucon で SSH 接続ができます。

また、AWSマネージメントコンソールからセッションマネージャーによる接続も可能です。セッションマネージャーで接続した場合は ssm-user というユーザーになるため、sudo su - isucon で isucon ユーザーに切り替えてください。

サーバーの IP アドレスはポータルか、AWS マネジメントコンソールの EC2 インスタンスページから確認できます。

サーバーへ接続後、下記のコマンドを実行することで正しく起動しているか検証が行えます。

$ sudo /usr/local/bin/isucon-env-checker

アプリケーションの動作確認

ISUPORTS には、サーバーのWeb ブラウザから HTTPS でアクセスできます。

動作確認のためのhostsファイル設定

ISUPORTSはホスト名に依存した挙動があるため、ブラウザにサーバーのIPアドレスを直打ちする形での閲覧はできません。以下の手順でhostsファイルを編集し、動作確認のためのホスト名が競技サーバーのIPアドレスにつながるようにします。

Mac や Linux であれば /etc/hosts に、 Windows であれば C:\Windows\System32\drivers\etc\hosts に以下の行を追記します。${サーバー IP アドレス} はサーバーの IP アドレスに読み替えてください。

${サーバー IP アドレス} admin.t.isucon.dev
${サーバー IP アドレス} isucon.t.isucon.dev
${サーバー IP アドレス} kayac.t.isucon.dev

上記変更の反映にはブラウザの再起動が必要な場合があります。

SSHポートフォワードを用いた動作確認

また、SSHポートフォワードを用いると、/etc/hosts に記述したテナント以外も閲覧できます。以下はコマンドの例です。

$ ssh -N -L443:localhost:443 isucon@${サーバ IP アドレス}

ISUPORTS へのログイン

ISUPORTSのフロントエンドは自動的に適切な認証情報を取得するため、ログインのID及びパスワードは不要です。

テナント/アカウント例

初期データにあらかじめ組み込まれているテナントと参加者アカウントIDのペアを以下に示します。

テナント名 アカウントID
isucon 0001
kayac 0002

SaaS管理者としてログイン

https://admin.t.isucon.dev をブラウザで開き、「アカウント名」は変更しない状態で、「認証する」ボタンを押します。

テナント管理者としてログイン

https://isucon.t.isucon.dev(テナント/アカウント例参照)をブラウザで開き、右上の「テナント管理者モードに切り替える」ボタンを押します。

参加者としてログイン

https://isucon.t.isucon.dev(テナント/アカウント例参照)をブラウザで開き、アカウントIDに0001(テナント/アカウント例参照)を入力して、「認証する」を押します。

ベンチマーカーの実行

負荷走行はポータル上からリクエストします。

ポータル にアクセスし、「Job Enqueue Form」から負荷走行対象のサーバーを選択、「Enqueue」をクリックすることで負荷走行のリクエストが行われ、順次開始されます。

なお、負荷走行が待機中(PENDING)もしくは実行中(RUNNING)の間は追加でリクエストを行うことはできません。

競技環境について

環境情報の確認と送信

サーバー起動(再起動を含む)時に競技環境が主催者の指定した環境で構築されているかを確認し、サーバー IP アドレスを含む環境情報をポータルに送信する処理が実行されます。

ポータルは送信された環境情報を元に、ポータル上に表示されるサーバー IP アドレス等のサーバー情報を更新します。なお、これはサーバー単位で更新されます。

この処理はサーバー起動時以外に、以下のコマンドで選手自らが行えます(競技環境構築で案内したコマンドと同一です)。

$ sudo /usr/local/bin/isucon-env-checker

競技環境の再構築方法

選手自らが設定変更等により競技環境を破壊するなどして、初期状態に戻す必要がある場合は上記「競技環境構築と接続」を参考に選手自らが AWS CloudFormation で新たに競技環境の構築を行うことになります。再構築以前の競技環境上で変更を加えたソースコードや設定ファイル等の移行が必要な場合は、各チームの責任で行ってください。

なお、サーバーの起動・停止・再起動は AWS マネジメントコンソールや API から選手が行っても構いません。

後述する「複数スタック」の問題を回避するため、再構築作業完了後は以前の AWS CloudFormation スタックを削除することをおすすめします。

複数スタックについて

ポータルからダウンロードしたテンプレートを利用して AWS CloudFormation スタックを複数作成しても構いません。ただし、以下の点に留意してください。

まず、「環境情報の確認と送信」で言及した通り、サーバー情報の更新はサーバー単位、かつサーバーが起動(再起動を含む)するたびに実施されます。 そのため、複数のスタックで作成されたサーバーが同時に存在している時、選手の操作によっては、ポータル上のサーバー情報が複数のスタックに跨ってしまう場合(混在)があります。

競技時間中は混在した状態になってしまっても問題ありませんが、競技終了時点でポータル上のサーバー情報が混在していた場合は失格となります。

主催者はポータルに登録された環境以外のサポートや、混在した状態でのサポートは行いません。

なお、混在しているかの判断はポータルとスタックのリソースに表示されている IP アドレスを元に行ってください。

重要事項

  • 競技終了後は主催者からアナウンスがあるまで競技環境のシャットダウンや停止などは行わず、3 台とも起動した状態を維持してください。
    • 競技時間中の再起動や一時的な停止に関しては問題ありません。
  • 競技に利用できる計算機資源は主催者が公開した CloudFormation テンプレートの内容に沿って起動された EC2 インスタンスのみです。
    • 例えば、テンプレートで作成されたリソースを、その内容に沿わなくなる変更(例: インスタンスタイプの変更)を行った状態で、競技に利用すると失格となります。
    • 競技終了時点で 環境情報の確認 に失敗する状態の場合、失格となります。
    • 競技終了時点でポータル上のサーバー情報に複数環境(スタック)が混在した状態の場合、失格となります。
    • レギュレーションに記載した通り、モニタリングやテスト、開発において外部の資源を用いても構いませんが(例: メトリクス計測サービス)、スコアを向上させるいかなる効果を持つものであってはいけません。これは前述している複数環境の利用も含みます。
  • 競技終了後は、主催者が追試を行います。Discord サーバー および https://isucon.net にて主催者がアナウンスをするまで、競技環境の操作はしないでください。
    • 競技終了後、別途アナウンスがあるまでの作業や操作(削除を含む)は失格となります。なお、アナウンスは結果発表後の予定です。
    • 競技環境の削除は、各チームで行う必要があります。削除を行わなかったために発生した不利益について、主催者は一切の責任を負いません。削除を行ってよいタイミングについても、結果発表後にアナウンスの予定です。

変更してはいけない点

下記は追試や環境確認に利用するため、変更した場合は失格となります。

  • isucon-env-checker.serviceに関わるファイル
    • /etc/systemd/system/isucon-env-checker.service
    • /etc/systemd/system/multi-user.target.wants/isucon-env-checker.service
    • /opt/isucon-env-checker 内のファイル
    • /usr/local/bin/isucon-env-checker
  • blackauth に関わるファイル
    • /etc/systemd/system/blackauth.service
  • その他、主催者による追試を妨げる変更(例: サーバー上の isucon 以外のユーザに関する、ユーザ削除や既存の公開鍵の削除)

参考実装

下記の言語での実装が提供されています。

  • Go
  • Node.js
  • Perl
  • PHP
  • Python
  • Ruby
  • Rust
  • Java

参考実装の切り替え方法

初期状態では Go による実装が起動しています。

各言語実装は Docker Compose で実行されていますが、起動は systemd で管理されています。 参考実装を Go から他の言語に切り替えるには以下手順を実行します。

1. /etc/systemd/system/isuports.servicedocker-compose-go.ymldocker-compose-{言語名}.yml に変更します。
ExecStart=docker compose -f docker-compose-ruby.yml up --build  # go -> ruby
ExecStop=docker compose -f docker-compose-ruby.yml down
2. isuports.service を再起動します。
$ sudo systemctl daemon-reload
$ sudo systemctl restart isuports.service

PHPへの切り替え

ただし、PHP を使う場合のみ、systemd の設定変更の他に、次のように nginx の設定ファイルの変更が必要です。

$ sudo unlink /etc/nginx/sites-enabled/isuports.conf
$ sudo ln -s /etc/nginx/sites-available/isuports-php.conf /etc/nginx/sites-enabled/isuports-php.conf
$ sudo systemctl restart nginx.service

データベースのリカバリ方法

参考実装では、初期化処理(POST /initialize)においてデータベースをベンチマーカーが想定している状態に戻します。 以下のコマンドでもデータベースを初期化できます。

$ ~isucon/webapp/sql/init.sh

初期化処理は用意された環境内で、ベンチマーカーが要求する範囲の整合性を担保します。 サーバーサイドで処理の変更・データ構造の変更などを行う場合、この処理が行っている内容を漏れなく提供してください。

MySQLのデータについては、/home/isucon/webapp/sql/admin/ 以下にインスタンス作成時点のdumpファイルがあります。POST /initializeinit.sh ではこのdumpファイルは使用されません。

SQLite3のデータについては /home/isucon/initial_data 以下にインスタンス作成時点のデータベースファイルがあります。

POST /initializeinit.sh では、このデータベースファイルが使用されます。

MySQLへのログイン方法

参考実装のMySQLに管理者権限で接続するには以下のようにします。

$ mysql -uroot -p isuports
Enter password:<rootと入力>

/etc/hosts ならびに isuports-1-3.t.isucon.dev ドメインについて

サーバーには初期状態で、3 台のサーバーの IP アドレスが事前に /etc/hosts へ登録されています。これらのホスト名は自由に利用して構いません。ベンチマーカーは下記のホスト名に対して接続します。

192.168.0.11 isuports-1.t.isucon.dev
192.168.0.12 isuports-2.t.isucon.dev
192.168.0.13 isuports-3.t.isucon.dev

また、サーバーに設定されている TLS 証明書は subject name が *.t.isucon.dev であるため、このホスト名で HTTPS 接続を行うと TLS 証明書の検証エラーは発生しません。ベンチマーカーはこれを期待します。

なお、*.t.isucon.dev の FQDN に関しては 127.0.0.1(IPv6 は ::1)の DNS レコードが登録されています。必要に応じて、検証や開発などで活用してください。

負荷走行について

ベンチマーカーによる負荷走行は以下のように実施されます。

  • 初期化処理の実行 POST /initialize(30 秒でタイムアウト)
  • アプリケーション互換性チェック(数秒~数十秒)
  • 負荷走行(60 秒)

初期化処理もしくはアプリケーション互換性チェックに失敗すると、負荷走行は即時失敗(fail)になります。

負荷走行終了時点で HTTP レスポンスの処理を打ち切ります。未完了のリクエストなどは強制的に切断されます。

負荷走行の打ち切り

負荷走行中にエラーが発生した場合、スコア計算において減点が発生します。

減点後のスコアが0点になることが確定した時点で負荷走行を打ち切り、負荷走行はfailとして扱われます。

減点の詳細は後述する「スコア計算」を参照してください。

例: Criticalなエラーが7個、それ以外のエラーが30個発生した時点で負荷走行スコアの100%が減点となり、スコアが0点になることが確定したためこの時点で負荷走行は打ち切られます。

反映までの猶予時間について

一部APIは他のリクエストへの反映までに許容される猶予時間があります

  • POST /api/organizer/competition/:competition_id/finish
    • 以下のエンドポイントは上記APIの情報の反映まで、レスポンスを返してから3秒の猶予が許容されます
      • GET /api/organizer/billing
      • GET /api/admin/tenants/billing
  • POST /api/organizer/player/:player_id/disqualified
    • 以下のエンドポイントは上記APIの情報の反映まで、レスポンスを返してから3秒の猶予が許容されます
      • GET /api/player/player/:player_id
      • GET /api/player/competition/:competition_id/ranking
      • GET /api/player/competitions

429 Too Many Requestsについて

以下のAPIは、Retry-Afterを含めた429 Too Many Requestsを返すことが出来ます。

  • POST /api/admin/tenants/add
  • POST /api/organizer/competitions/add

Too Many Requestsを返した場合は、ベンチマーカーは点数を加算せずRetry-Afterの秒数待ったのちリトライします。

ベンチマーカーの認証について

ベンチマーカーはblackauthを利用せずに、ベンチマーカー自らがJWTを発行してリクエストを行います。よって、blackauthは負荷走行時に利用しません。

しかし、提供されているWebフロントエンドはblackauthが提供するエンドポイントを利用しているため、運営の目視による追試の際に必要なので停止しないでください。

スコア計算

スコアは一度のリクエストの成功につき、エンドポイント毎に決められた点数が加算されます。

  • 1点
    • GET /api/player/player/:player_id
    • GET /api/player/competition/:competition_id/ranking
    • GET /api/player/competitions
  • 10点
    • POST /api/admin/tenants/add
    • GET /api/admin/tenants/billing
    • GET /api/organizer/players
    • POST /api/organizer/players/add
    • POST /api/organizer/player/:player_id/disqualified
    • POST /api/organizer/competitions/add
    • POST /api/organizer/competition/:competition_id/finish
    • POST /api/organizer/competition/:competition_id/score
    • GET /api/organizer/billing
    • GET /api/organizer/competitions

APIが予期しないResponseCode、あるいは正常ではないレスポンスを返した場合はエラーと判定します。

以下のAPI及び条件についてはCriticalなエラーとします。

  • POST /api/admin/tenants/add
  • POST /api/organizer/competitions/add
  • POST /api/organizer/competition/:competition_id/score
  • POST /api/organizer/competition/:competition_id/finish
  • POST /api/organizer/player/:player_id/disqualified
  • GET /api/player/* を失格済みプレイヤーでリクエスト

エラーが発生した場合は、負荷走行スコアから (エラーの数 × 1)% が減点されます。ただしCriticalなエラーについては、負荷走行スコアから (エラーの数 × 10)% が減点されます

例: 負荷走行のスコアが3000点、Criticalなエラーが2個、それ以外のエラーが5個の場合 (10 × 2) + (1 × 5) = 25でスコアから25%減点されます。 よって減点後のスコアは 3000 - (3000 × 0.25) = 2250 で2250点となります。

最終スコア

予選競技中の最終計測を最終スコアとします。以下に述べる追試でfailになったチームを取り除いた最終スコアに基づいて予選の順位を決定します。

追試

競技終了後、主催者は全サーバーの再起動後に負荷走行を実施し再現スコアを計測します。主催者による確認作業(追試)を行います。下記の点にあてはまる場合の最終スコアは fail とします。

全チームに対して行う追試項目
  • 再起動後の負荷走行でfailした場合
  • 再現スコアが最終スコアの85%以下の場合
最終スコアで上位のチームに対して行う追試項目
  • 負荷走行実行時にアプリケーションに書き込まれたデータが、サーバー再起動後に取得できない場合
  • アプリケーションのブラウザ上での挙動が、初期状態と同様に保たれていない場合
POST /initialize での実装言語の出力

POST /initialize レスポンスにて、本競技で利用した言語を出力してください。参考実装はそのようになっています。この情報は集計し ISUCON 公式Blog での公表や、参考情報として利用させていただきます。

POST /initialize のレスポンスは以下のような JSON となります。

{
  "lang": "実装言語"
}

lang の値が実装に利用した言語となります。 lang が空の場合は初期化処理が失敗と見なされます。

禁止事項

以下の行為を特に禁止とします。

  • 競技終了時間までに、競技の内容に関するあらゆる事項(問題内容・計測ツールの計測方法など)を公開・共有すること(内容を推察できる発言も含む)
    • 不特定多数への公開はもちろん、他チームの選手と連絡を取り、問題内容等を共有する事(結託行為)も禁止とする。
    • ただし主催者が Twitter, Web サイトにおいて公開している情報は除く。ポータルでログインを要するページ(選手が参加する Discord を含む)において記載されている内容は公開情報でない旨留意すること
  • 競技時間中、チーム外の人物と ISUCON12 問題にまつわる事項のやりとり(ISUCON12 選手であるかどうかを問わない、SNS での発言も含む)
  • 主催者の指示以外で利用が認められたサーバー以外の外部リソースを使用する行為(他のインスタンスに処理を委譲するなど) は禁止する。
    • ただしモニタリングやテスト、開発などにおいては、PC や外部のサーバーを利用しても構わない。
    • デプロイのために外部のコンテナレジストリ (Amazon ECRなど) を利用することも可能。ただし、競技終了まで他のチームに対して公開されないように注意すること
  • 選手が主催者からその選手が属するチームへ提供されていないサーバーについて直接のアクセスを試みる行為や、外部への不正アクセスを試みる行為。具体的にはベンチマーカーへのログイン試行等。(なお、例示のため、これに限らない)
  • 他チームと結託する行為(程度を問わず)
  • 主催者が他チームへの妨害、競技への支障となるとみなす全ての行為
  • 本マニュアルやレギュレーション、ポータルにおいて禁止とされた行為(禁止事項)への違反は、失格とします。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment