あらすじ
ISUCON7 でまたもや予選敗退したんですが来年に備えて復習しておきたいので環境を構築してみました。
やること
[訂正]ディスクプランは HDD ではなくて SSD でした。
さくらのクラウドで 1GB/1仮想コア、ディスクプランは SSD 。これを3台構築。あとスイッチを1台追加してこれとサーバーをつなぎます。host名をそれぞれ app1, app2, app3(db) として、最初に app1 を作ってから app2 と app3 をクローンしていきます。
完成予想図はこんな感じです。さくらのクラウド触った事がある人だったら簡単だと思います。私は初めて触ったのでちょっと手こずりましたが。
やった事
ほとんど README.md に書いてあるんですが、まあこの記事は自分の為の備忘録なので...
github.com
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
というわけで
これから予選を突破した人たちのブログを読んでしっかり復習したいと思います。