ISUCON7(予選)過去問環境をConoHaで構築する手順

インフラ

こんにちは。仁科(@nishina555)です。

Webのパフォーマンスチューニングの有名な大会にISUCONというものがあります。

ISUCONの読み方は『イスコン』で、ISUCONの名前の由来は『II kanji ni Speed Up CONtest(いい感じにスピードアップコンテスト)』の頭文字からきています・・・とぼくはずっと思っていたのですが、本当の名前の由来は『椅子』からきています。

―― 「ISUCON」の名前の由来は
櫛井:最初は全然違う名前で考えていたんです。でも、あまりいい名前じゃなくて。当時、エンジニアがサーバーをチューニングしていくときにあまりにひどい構成だと「椅子を投げるぞ」という言葉が流行っていて(笑)、募集開始5分前に「だったら“椅子”って言葉を入れちゃえば」ということで、「ISUCON」に決まりました(笑)。
引用: サーバーとアプリを高速化、さばけるアクセス数を競う「ISUCON 3」レポート

ISUCONで好成績を残すためには知識量の多さはもちろん大事ですが、過去問解いてISUCONの進め方や実践に慣れるということも非常に重要になってきます。

ISUCONの過去問を解く重要性は認知されており、vagrant-isucondocker-isuconなどISUCON環境構築用のリポジトリがいくつか公開されております。
また、公式のリポジトリにも感想戦用の環境構築手順が公開されています。

すでに公開されているリポジトリを利用すれば自分でISUCONの環境を構築できるのですが、若干面倒でもあります。

また、パフォーマンスチューニングという言葉に興味はあるけれどなにから手をつければいいかよくわからないという方も多いと思います。

しかし、この度なんとConoHaでISUCON7(予選)のイメージファイルが提供されるという朗報がありました!

ConoHaはGMOが提供しているVPSです。
ConoHaを利用すればあっという間にISUCONの予選問題の環境を構築することができるので、ISUCONのイメージがあまりわいていない方にもオススメです。

また、VPSにISUCONの環境を構築することで、チームメンバーと共同で作業することができるため本番さながらの実践練習を行えるようになります。

今回、ConoHaを利用してISUCON7(予選)の環境を構築したので手順について説明をします。
そして、実際に構築した環境のベンチマークを取るまでの手順についてもあわせて説明します。

今回のゴール
  • ISUCON7(予選)の環境をVPSに構築する
  • ISUCON7(予選)のディレクトリ構成を理解する
  • VPSに公開鍵認証でssh接続する
  • データのバックアップ方法を理解する
  • 実装言語の切り替えを理解する
  • ベンチマークの実行を行いスコアを確認する

ConoHaのVPSサーバーに登録する

まずはConoHaに登録をし、ISUCON7(予選)環境をVPSに構築します。

ConoHaのユーザー登録をする

まずはConoHaのユーザー登録をします。ユーザー登録は『こちら』から行います。

アカウントを持っている人はアドレスとパスワード、持っていない人はユーザー情報を記入します。

支払い方法を選択する

次に支払い方法を選択します。SMS認証をおこなった後、支払い方法が選択できます。

ConoHaの支払い方法には以下の3つがあります。

ConoHaの支払い方法
  • ConoHaカード
  • ConoHaチャージ
  • クレジットカード
ConoHaカード『こちら』から購入できます。デジタル版もあるので購入後すぐに利用できます。

ConoHaチャージはあらかじめお金を入金しておき、そこから利用分の金額が引き落とされるサービスです。
ConoHaチャージに関する詳細はConoHaホームページの『ConoHaチャージへのチャージ(入金)』をご覧ください。

なお、ConoHaのVPS利用が1ヶ月に満たない場合は、時間単位の利用料金が適用されます。
ConoHaの料金システムの詳細はConoHaホームページの『料金・支払い方法』をご覧ください。

VPSを申し込む

次にVPSのリージョン、サービス、イメージタイプを選択します。

イメージタイプの『アプリケーション』に『ISUCON7(予選)』というものがあるので、それを選択します。

動作確認をする

VPSを申し込むと以下のようなダッシュボード画面になります。

サーバーリストに先ほど申し込んだVPSが登録されていることがわかります。
ステータスが『起動中』であればサーバーにアクセスすることができます。

登録時点でアプリケーションはすでに起動しています。
http://[IPアドレス] と入力し、以下のような画面が出ればOKです。

サーバーにログインする

アプリが動作していることが確認できたので、今度はローカル環境からサーバーにログインしてみます。

VPSを契約するときに作成したパスワードを利用してrootユーザーでsshしてみます。
-lオプションでログインするユーザーを指定しています。

$ ssh -l root [IPアドレス]

isuconユーザーのパスワードを変更する

ISUCONではisuconというユーザーで作業をしていくことになります。

rootユーザーでpasswd ユーザー名と入力すると任意のユーザーのパスワードを変更できるので、isuconユーザーのパスワードを変更しておきます。

[root]
$ passwd isucon

Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully

なお、サーバーに存在するユーザーは/etc/passwdで確認することができます。
cut -d: -f1 /etc/passwdでユーザー名のみを抽出することができます。

isuconユーザーでサーバーにログインする

isuconユーザーのパスワードを更新したので、パスワード認証でsshできるか確認してみます。
isuconユーザーでログインするには以下のようにします。

$ ssh -l isucon [IPアドレス]

なお、rootユーザーでsshした後にisuconユーザーに切り替える場合は su - isucon で切り替えられます。

公開鍵認証でサーバーにログインする

isuconユーザーでssh接続できることが確認できました。
しかし、毎回パスワード認証でログインをするのは面倒なので公開鍵認証でログインできるようにしておきます。

ここでは例としてconoha-isucon-keyという秘密鍵とconoha-isucon-key.pubという公開鍵のペアを作成し、conoha-isuconと名付けたVPSに公開鍵認証でssh接続できるようにする手順を説明します。

コマンドの意味などの詳細は以下の記事を参考にしてみてください。

リモートサーバーに公開鍵認証でssh接続するための手順

なお、ここで行う鍵の作成とconfigの編集作業はVPS上ではなく、ローカル環境で行うものですので注意してください。
$ cd ~/.ssh
$ ssh-keygen -t rsa -f conoha-isucon
$ chmod 600 conoha-isucon
$ ssh-copy-id -i ~/.ssh/conoha-isucon.pub isucon@[IPアドレス]
$ vim ~/.ssh/config

#---------
Host conoha-isucon
  Hostname [IPアドレス]
  User isucon
  IdentityFile ~/.ssh/conoha-isucon
  Port 22
#---------

上記の設定をすることで、以下コマンドでisconユーザーとしてVPSにログインできるようになります。

$ ssh conoha-isucon

isuconのディレクトリ構成について

isconのホームディレクトリにはisubataというディレクトリがあります。
isubata の配下には以下のようなディレクトリが存在しています。

ディレクトリ名 役割
db データベーススキーマ等
bench ベンチマーカー、初期データ生成器
webapp 各種言語実装
files 各種設定ファイル

ディレクトリ構造の詳細は以下のようになっています。

なお、treeコマンドはデフォルトではインストールされていないのでsudo apt-get install treeでインストールしています。

$ cd /home/isucon/isubata
$ tree -L 2
.
├── bench
│   ├── bin
│   ├── data
│   ├── isucon7q-initial-dataset.sql.gz
│   ├── Makefile
│   ├── pkg
│   ├── src
│   └── vendor
├── db
│   ├── init.sh
│   └── isubata.sql
├── files
│   ├── app
│   ├── bench
│   └── db
├── provisioning
│   ├── allinone
│   ├── Makefile
│   ├── manifest_allinone.json
│   ├── misc
│   └── packer_variables.json
├── README.md
└── webapp
    ├── go
    ├── nodejs
    ├── perl
    ├── php
    ├── public
    ├── python
    └── ruby

実装言語の確認

ISUCONのアプリケーションを実装している言語は複数存在し、選択することができます。

ISUCON7(予選)では以下の言語の中から選択が可能です。

ISUCON7(予選)で選択可能な実装言語
  • Go
  • Node.js
  • Perl
  • PHP
  • Python
  • Ruby

psコマンドでアプリケーションのプロセスを確認してみるとデフォルトではPythonが利用されていることがわかります。

なお、psコマンドのオプションの意味は以下のようになっています。

オプション 意味
a 自分以外のユーザーのプロセスについても表示
u デーモンプロセスを表示
x ユーザー名と開始時刻を表示
$ ps aux|grep python

isucon 2453 1.2 4.6 63524 23232 ? Ss 00:35 0:00 /home/isucon/isubata/webapp/python/venv/bin/python3 /home/isucon/isubata/webapp/python/venv/bin/gunicorn --workers=4 --threads=4 app:app -b 127.0.0.1:5000
isucon 2458 0.5 5.8 104992 29060 ? S 00:35 0:00 /home/isucon/isubata/webapp/python/venv/bin/python3 /home/isucon/isubata/webapp/python/venv/bin/gunicorn --workers=4 --threads=4 app:app -b 127.0.0.1:5000
isucon 2460 0.5 5.8 104992 29060 ? S 00:35 0:00 /home/isucon/isubata/webapp/python/venv/bin/python3 /home/isucon/isubata/webapp/python/venv/bin/gunicorn --workers=4 --threads=4 app:app -b 127.0.0.1:5000
isucon 2461 0.5 5.8 104996 29064 ? S 00:35 0:00 /home/isucon/isubata/webapp/python/venv/bin/python3 /home/isucon/isubata/webapp/python/venv/bin/gunicorn --workers=4 --threads=4 app:app -b 127.0.0.1:5000
isucon 2462 0.5 5.8 104996 29068 ? S 00:35 0:00 /home/isucon/isubata/webapp/python/venv/bin/python3 /home/isucon/isubata/webapp/python/venv/bin/gunicorn --workers=4 --threads=4 app:app -b 127.0.0.1:5000
isucon 2489 0.0 0.1 14224 944 pts/0 S+ 00:35 0:00 grep --color=auto python

参照実装の切り替え方法

各言語実装は systemd で管理されています。例えば、参照実装をGoに切り替えるには次のようにします。 【参考】 ISUCON7予選 当日マニュアル.mdの参照実装の切り替え方法

$ sudo systemctl stop isubata.python.service
$ sudo systemctl disable isubata.python.service
$ sudo systemctl start isubata.golang.service
$ sudo systemctl enable isubata.golang.service

実際に言語を切り替えてからプロセスを再度確認するとgoでアプリケーションが動いていることがわかります。

$ ps aux | grep go

isucon 2334 0.0 1.4 115076 7288 ? Ssl 00:32 0:00 /home/isucon/isubata/webapp/go/isubata
isucon 2403 0.0 0.1 14224 956 pts/0 S+ 00:33 0:00 grep --color=auto go
PHPの実装で動かす場合には、[/home/isucon/env.sh]の[ISUBATA_DB_HOST]を[localhost]から[127.0.0.1]に変える必要があります。

ベンチマークの実行

ベンチマークとは負荷走行のことです。ベンチマークを実行するとアプリケーションの性能がスコアという数値で評価されます。

このスコアこそがISUCONで競われる値で、限られた時間と制約の中でどれだけのスコアを出すことができるかがISUCONの競技内容となっております。

ベンチマークは以下のコマンドで実行します。

$ /home/isucon/isubata/bench/bin/bench -data=/home/isucon/isubata/bench/data -remotes=localhost -output=result.json

[isu7q-bench] 2018/07/03 04:09:00.709578 dataset.go:37: datapath /home/isucon/isubata/bench/data
[isu7q-bench] 2018/07/03 04:09:01.260221 bench.go:472: Remotes [localhost]
[isu7q-bench] 2018/07/03 04:09:01.260421 bench.go:346: State.Init()
[isu7q-bench] 2018/07/03 04:09:01.275470 bench.go:348: State.Init() Done
...
...
...
(以下省略)

ベンチマークスコアの確認

ベンチマークの実行内容は-outputオプションで指定したファイルに出力されます。
先ほどの場合だとresult.jsonというファイルに書き込まれています。

jqコマンドを利用することでjsonファイルの結果を見やすい形に整形してくれます。scoreというフィールドがベンチマークスコアになります。以下の例では5697がスコアになっています。

ちなみにISUCON7の予選通過のボーダーはおよそ20万点です。【参考】『ISUCON7 本選出場者決定のお知らせ』

$ pwd
/home/isucon/isubata
$ jq . < result.json
{
  "job_id": "",
  "ip_addrs": "localhost",
  "pass": true,
  "score": 5697,
  "message": "ok",
  "error": [
    "2018-07-03 04:09:44.858709483 +0900 JST m=+44.170155219 リクエストがタイムアウトしました (POST /login )",
    "2018-07-03 04:09:44.862650562 +0900 JST m=+44.174096331 リクエストがタイムアウトしました (POST /login )",
    "2018-07-03 04:09:44.863713764 +0900 JST m=+44.175159562 リクエストがタイムアウトしました (POST /login )",
    "2018-07-03 04:09:44.864426262 +0900 JST m=+44.175871983 リクエストがタイムアウトしました (POST /login )",
    "2018-07-03 04:09:44.865481164 +0900 JST m=+44.176926908 リクエストがタイムアウトしました (POST /login )",
    "2018-07-03 04:09:44.866289066 +0900 JST m=+44.177734797 リクエストがタイムアウトしました (POST /login )",
    (以下省略)

初期データの投入

アプリケーションはisubataというDBを利用するのですが、該当のDBには初期状態ではデータが入っていません。

MySQLに接続してDBの中身を確認してみます。
なお、\GはSQLの結果を縦に表示させるためのデリミタなので、手元で確認する場合は通常の;で問題ありません。

$ sudo mysql

mysql> show databases\G
*************************** 1. row ***************************
Database: information_schema
*************************** 2. row ***************************
Database: isubata
*************************** 3. row ***************************
Database: mysql
*************************** 4. row ***************************
Database: performance_schema
*************************** 5. row ***************************
Database: sys
5 rows in set (0.00 sec)

mysql> use isubata
Database changed

mysql> show tables\G
*************************** 1. row ***************************
Tables_in_isubata: channel
*************************** 2. row ***************************
Tables_in_isubata: haveread
*************************** 3. row ***************************
Tables_in_isubata: image
*************************** 4. row ***************************
Tables_in_isubata: message
*************************** 5. row ***************************
Tables_in_isubata: user
5 rows in set (0.00 sec)

mysql> select count(1) from message\G
*************************** 1. row ***************************
count(1): 0
1 row in set (0.01 sec)

初期データは~/isubata/benchにあるisucon7q-initial-dataset.sql.gzという圧縮ファイルの中に存在しています。
以下のようにすることで、圧縮ファイルに存在する初期データを投入することができます。

$ zcat ~/isubata/bench/isucon7q-initial-dataset.sql.gz | sudo mysql isubata --default-character-set=utf8mb4

再度MySQLに接続するとレコードが存在することがわかります。

mysql> select count(1) from message\G
*************************** 1. row ***************************
count(1): 10000
1 row in set (0.01 sec)

データのリカバリ方法

環境構築の手順からは少し脱線をしますが、データのリカバリ方法についても説明をしておきます。

チューニングや実装を進めていく過程でデータベースを初期状態に戻したい場合があります。
その場合は、dbディレクトリにあるinit.shというシェルを実行するとデータベースの初期化が行われます。

init.shを実行するとisubata DBに保存されているデータは全て削除されるので注意してください。

init.shを実行後、初期データを投入すれば初期データのみが存在するはじめの状態にデータをリカバリすることができます。

$ pwd
/home/isucon/isubata/db
$ sudo ./init.sh
$ zcat ~/isubata/bench/isucon7q-initial-dataset.sql.gz | sudo mysql --default-character-set=utf8mb4

シャットダウン方法

VPSのシャットダウンはConoHaのダッシュボード上で行うことができます。

起動の場合も同様の手順で『起動』ボタンを押せばOKです。

Gitでソースコードを管理する

パフォーマンスチューニングをするにあたり、ソースコードなどを修正することになるのでgitで管理できるようにしておくと便利です。

ConoHaではすでにgitの環境が整っているのですが、リモートリポジトリの向き先が公式のリポジトリのため、自分のアカウントに変更しておいたほうがよりよいです。
手順については以下の記事にまとめてあるので、興味がある方は参考にしてみてください。

ConoHaのISUCON環境をGitで管理できるようにする方法

(補足) VPSのセキュリティ設定をしておく

ISUCONの話から少し脱線をするのですが、今までの手順で環境を構築した場合、rootユーザーで直接ssh接続が可能な状態のままだと思います。

rootユーザーでssh接続ができるのはセキュリティ的にはあまりよくありません。

ネットにVPSを公開し続けおり、気がついたら悪意のあるユーザーに利用されているという可能性もなきにしもあらずなので、最低限のセキュリティ対策もしておいたほうが安全です。

VPSのセキュリティ設定の手順については以下の記事に書きましたので参考にしてみてください。

【チュートリアル】VPSを借りたらやるべき最低限のセキュリティ初期設定

まとめ

以上でISUCON7(予選)過去問環境をConoHaで構築する手順の説明を終わります。

ログイン方法、ベンチマークの実行方法、データバックアップなどについても一通り確認をしたため、これでパフォーマンスチューニングを練習する環境が整いました。

どのようにすればベンチマークスコアがあがるのかチューニング方法を分析したり、チームメンバーとVPSを共有して予選当日の流れを確認したりなどConoHaを最大限に活用してISUCON予選にむけて頑張りましょう!

環境構築が終わったらモニタリングの設定を始めることをオススメします↓↓↓↓

alpのインストールからNginxのアクセスログ解析までの手順【ISUCON】

遅いクエリを突き止める!MySQLクエリ解析にスロークエリログを導入する手順

リアルモニタリングツールnetdataのインストールと利用方法【ISUCON】

PR