あいつの日誌β

働きながら旅しています。

さくらクラウド上で ISUCON7 予選の環境を構築してみた

あらすじ

ISUCON7 でまたもや予選敗退したんですが来年に備えて復習しておきたいので環境を構築してみました。

やること

[訂正]ディスクプランは HDD ではなくて SSD でした。

さくらのクラウドで 1GB/1仮想コア、ディスクプランは SSD 。これを3台構築。あとスイッチを1台追加してこれとサーバーをつなぎます。host名をそれぞれ app1, app2, app3(db) として、最初に app1 を作ってから app2 と app3 をクローンしていきます。

完成予想図はこんな感じです。さくらのクラウド触った事がある人だったら簡単だと思います。私は初めて触ったのでちょっと手こずりましたが。

f:id:okamuuu:20171024225504p:plain

やった事

ほとんど README.md に書いてあるんですが、まあこの記事は自分の為の備忘録なので...

github.com

ubuntu でログイン

sudo apt update
sudo apt install -y git vim mysql-server nginx
sudo update-alternatives --set editor /usr/bin/vim.basic

isucon ユーザーを作成

isucon ユーザーを作成

sudo adduser isucon

sudo visudo で NOPASS にする。最終行に以下を追記

isucon ALL=NOPASSWD: ALL

isucon ユーザーでログインできるようにする

sudo su isucon
cd
mkdir .ssh/
chmod 700 .ssh
cd .ssh
touch authorized_keys
chmod 600 authorized_keys  # authorized_keys に公開鍵を追加する

ssh秘密鍵でのみログインできるようにする(パスワード・チャレンジレスポンスでの SSH を許可しないにチェックを入れていれば不要)

sudo vi /etc/ssh/sshd_config
#PasswordAuthentication yes
PasswordAuthentication no

ssh 再起動

$ sudo service ssh restart

環境構築

後は以下を参照

https://github.com/isucon/isucon7-qualify

使用言語を Perl に変更

環境が構築できたら使用する言語を systemd に登録します。 Perl の場合は https://github.com/isucon/isucon7-qualify/blob/master/files/app/isubata.perl.service にファイルがあります。

create /etc/systemd/system/isubata.perl.service

[Unit]
Description = isucon7 qualifier main application in perl

[Service]
WorkingDirectory=/home/isucon/isubata/webapp/perl
EnvironmentFile=/home/isucon/env.sh

ExecStart = /home/isucon/local/perl/bin/carton exec plackup -s Starlet -p 5000 app.psgi

Restart   = always
Type      = simple
User      = isucon
Group     = isucon

[Install]
WantedBy = multi-user.target

install cpan modules

cd /home/isucon/isubata/webapp/perl
/home/isucon/local/perl/bin/carton install

[追記]上記の service には /home/isucon/env.sh が存在する事を期待しているので追加しておきます

create /home/isucon/env.sh

ISUBATA_DB_HOST=127.0.0.1 # たぶん後で db に変更する事になる
ISUBATA_DB_USER=isucon
ISUBATA_DB_PASSWORD=isucon

start

sudo systemctl daemon-reload
sudo systemctl enable isubata.perl
sudo systemctl restart isubata.perl

ベンチが動作することを確認したら サーバーを2台 clone します。 clone するときに ファイルを修正する、にするとIPアドレスMACアドレスが変更されます。この時ファイルを修正する、にチェックを忘れると同一のMACアドレスが存在する事になりややこしい事になりますのでご注意ください。もし間違えたらクローンからやり直したほうが簡単だと思います。

プライベートネットワーク用スイッチを作成

スイッチを作成した後サーバーの Nic とスイッチを接続します。 サーバーを停止する必要があります。

ローカルネットワーク側サーバのネットワーク設定

https://knowledge.sakura.ad.jp/1272/

スイッチと接続した後に以下を各サーバーで実行します。

sudo ifconfig eth1 192.168.101.1/24 # app1
sudo ifconfig eth1 192.168.101.2/24 # app2
sudo ifconfig eth1 192.168.101.3/24 # app3 db

[追記]上記だと再起動後に設定が消えてしまうので以下のように /etc/network/interfaces を修正します。

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet static
address 59.106.xxx.xxx
netmask 255.255.255.0
gateway 59.106.xxx.xxx

### 追加する項目
auto eth1
iface eth1 inet static
address 192.168.101.1  # app1 の場合は末尾が1
netmask 255.255.0.0

反映させる

sudo /etc/init.d/networking restart 

各サーバーの /etc/hosts に以下を追記して名前解決できるようにします。

192.168.101.1   app1
192.168.101.2   app2
192.168.101.3   app3 db 

app1 と app 2 の MySQL を停止する。nginx, mysql を disable するとき若干 warning が出ます。

sudo systemctl stop mysql
sudo systemctl disable mysql

app3 の nginx と起動している isubata.perl.service を停止する

sudo systemctl stop nginx
sudo systemctl disable nginx

最後にベンチ

ベンチマークはリモートからだけどここでは app1 で実行する事にします。 注意点として プライベートネットワークではなく、外部IPを指定します。

プライベートとグローバルでは帯域が違うためスコアに影響が出ると思われます。

./bin/bench -remotes=59.106.xxx.xxx,59.106..xxx.xxx -output result.json

スコアだけみたい場合

./bin/bench -remotes=59.106.xxx.xxx,59.106.xxx.xxx -output result.json && cat $_ | jq .score

というわけで

これから予選を突破した人たちのブログを読んでしっかり復習したいと思います。