ISUCON の練習環境については色々記事がありますが、そもそも出たことない人にとってはまあまあハードル高く感じたので、一旦ベースのところから資料まとめていきたいなと思います

ISUCON 情報

当日の進め方 https://gist.github.com/matsukaz/6af9dd76d62e2cddb65fafa5b0636e9a

1.ISUCONで本選進出するために https://zenn.dev/tohutohu/articles/3dfabe751c743f

[NG]ISCUON11 の環境を簡単に構築できるらしい https://github.com/isucon/isucon11-qualify/tree/main/provisioning/cf-kakomon

[] ISUCON13 https://github.com/isucon/isucon13

summary

  • isucon13 でやったこと
    • AMI から EC2 インスタンス起動
    • 証明書使ってたので更新
    • bench側の信頼ストアに証明書投入
    • クライアント側で chromium 使用し、SSLエラーを無視して接続
    • ブラウザでの動作確認とベンチマーク起動によるポイント確認
  • ISUCON 12 とか、単一 EC2 じゃないタイプだとまた変わりそう

ISUCON13 検証

https://github.com/isucon/isucon13

  • ami-041289d910c114864 で EC2 を起動→まだある

EC2立ち上げてログイン。su で isucon user に切り替えてホームへ移動

pwd
/home/isucon

ls -l
total 39588
-rwxr-xr-x  1 root   root   40517898 Nov 27  2023 bench_linux_amd64
-rwxr-xr-x  1 isucon isucon      334 Nov  6 01:22 env.sh
drwxrwxr-x  3 isucon isucon     4096 Nov 27  2023 go
drwxr-xr-x  8 isucon isucon     4096 Nov 27  2023 local
drwxr-xr-x 13 isucon isucon     4096 Nov 24  2023 webapp```

tree -L 2 . ├── bench_linux_amd64 ├── env.sh ├── go │   └── pkg ├── local │   ├── golang │   ├── node │   ├── perl │   ├── php │   ├── python │   ├── ruby │   └── rustup-init.sh └── webapp ├── go ├── img ├── node ├── pdns ├── perl ├── php ├── public ├── python ├── ruby ├── rust └── sql



すでに nginx が立ち上がっている。
証明書は自己署名で、パブリックなドメインはないので、ローカルのhosts を編集して大会用ドメインを検証環境IPへ向ける

for ISUCON

xxx.xxx.xxx.xxx pipe.u.isucon.dev xxx.xxx.xxx.xxx test001.u.isucon.dev


cat /etc/nginx/nginx.conf


証明書ない気がする。デフォルト配置あるか?

ls /etc/nginx/tls -la total 36 drwxr-xr-x 2 root root 4096 Nov 27 2023 . drwxr-xr-x 9 root root 4096 Nov 6 01:25 .. -rw-r–r– 1 root root 5591 Nov 27 2023 _.t.isucon.dev.crt -rw-r–r– 1 root root 1675 Nov 27 2023 _.t.isucon.dev.key -rw-r–r– 1 root root 5256 Nov 27 2023 _.u.isucon.dev.crt -rw-r–r– 1 root root 3751 Nov 27 2023 _.u.isucon.dev.issuer.crt -rw-r–r– 1 root root 227 Nov 27 2023 _.u.isucon.dev.key



普通に証明書が切れている。uとtは何が違う?


openssl x509 -in _.u.isucon.dev.crt -text


    Validity
        Not Before: Jun 17 04:40:52 2022 GMT
        Not After : Sep 15 04:40:51 2022 GMT
    Subject: CN = *.t.isucon.dev


秘密鍵 key はあるので、再度証明書作る?いや鍵も作り直す



openssl req -x509 -nodes -sha512 -days 365
-newkey rsa:2048 -keyout server.key
-out server.pem -subj “/CN=.u.isucon.dev” -addext “subjectAltName = DNS:.u.isucon.dev, DNS:u.isucon.dev”



sudo vi ../nginx.conf


    ssl_certificate         /etc/nginx/tls/server.pem;
    ssl_certificate_key     /etc/nginx/tls/server.key;

sudo chmod 711 server.key sudo service restart nginx


仮IP

35.72.35.148



ローカルのホストでドメインを上のIPへ向ける

sudo vi /private/etc/hosts


for ISUCON

35.72.35.148 pipe.u.isucon.dev 35.72.35.148 test001.u.isucon.dev



うまくいかん
あ〜〜〜 `/etc/nginx/sites-enabled` これ読み込んでるのね

以下を差し替え

cat sites-enabled/isupipe.conf




https://pipe.u.isucon.dev/ へアクセス
ERR_CERT_AUTHORITY_INVALID
これは想定通り

cat して local に保存したけど無理

正味、chromium  をこれ用に使って TLS エラーをignore した方が早いかも

chromium –args –ignore-certificate-errors


一応 chromium 使うことで起動を確認


###  負荷かけてみる

pwd /home/isucon

./bench_linux_amd64 run

{“error”: “Post "http://pipe.u.isucon.dev:8080/api/initialize": 「pipe.u.isucon.dev」の名前解決に失敗しました。「35.72.35.148」はサーバーリストに含まれていません”} {“pass”:false,“score”:0,“messages”:[“初期化が失敗しました”,“initializeのリクエストに失敗しました Post "http://pipe.u.isucon.dev:8080/api/initialize": 「pipe.u.isucon.dev」の名前解決に失敗しました。「35.72.35.148」はサーバーリストに含まれていません”],“language”:“unknown”,“resolved_count”:0}


それはそう。bench が同じインスタンスだとそれはそう。これどうすrべき?


### ISUCON13 当日manual
https://github.com/isucon/isucon13/blob/main/docs/cautionary_note.md
- ISUPipe には、サーバーのWeb ブラウザから HTTPS でアクセスできます。
- ISUPipe へのログインは以下のアカウント情報を用いることができます。
	- test001
	- test
- 参考実装では2つのデータベースがあります。
	- isupipe アプリケーションが利用するデータベース
	- isudns PowerDNSのゾーン情報を格納するデータベース

- 変更してはいけない点
		- envcheck.serviceに関わるファイル
		- /etc/systemd/system/envcheck.service
		- /etc/systemd/system/multi-user.target.wants/envcheck.service
		- /opt/isucon-env-checker 内のファイル、バイナリファイル
	- aws-env-isucon-subdomain-address.service に関わるファイル
		- /etc/systemd/system/aws-env-isucon-subdomain-address.service
		- /etc/systemd/system/multi-user.target.wants/aws-env-isucon-subdomain-address.service
		- /opt/aws-env-isucon-subdomain-address.sh
	- isuadmin ユーザに関わるファイルおよびログイン情報
	- その他、主催者による追試を妨げる変更(例: サーバー上の isucon 以外のユーザに関する、ユーザ削除や既存の公開鍵の削除、サーバーの再起動の妨害)

- ポータルから負荷走行を実行した場合、指定したサーバー(IPアドレス)のDNSサーバー(53/UDP)に名前解決を行い、得られたIPアドレスに対してHTTPSでアクセスを行います。
	- サーバーに DNS サーバーも乗っかってるので最終的には DNS のレスポンスも微妙に影響するっぽい?
	- 負荷走行中、DNSサーバに対していわゆる「DNS水責め攻撃」が行われます。

- スコア計算
	- スコアは一回の負荷走行中にISUPipeの投げ銭(Tip)機能により、送金・寄付された金額(ISUCON)の合計となります。
	- スコアの合計額がサーバとベンチマーカーとで差分がある場合、ベンチマーカーで計測している値をスコアとします。


### 名前解決確認

dig pipe.u.isucon.dev @127.0.0.1 A +short 35.72.35.148

cat env.sh ISUCON13_MYSQL_DIALCONFIG_NET=“tcp” ISUCON13_MYSQL_DIALCONFIG_ADDRESS=“127.0.0.1” ISUCON13_MYSQL_DIALCONFIG_PORT=“3306” ISUCON13_MYSQL_DIALCONFIG_USER=“isucon” ISUCON13_MYSQL_DIALCONFIG_DATABASE=“isupipe” ISUCON13_MYSQL_DIALCONFIG_PARSETIME=“true” ISUCON13_POWERDNS_SUBDOMAIN_ADDRESS=“35.72.35.148” ISUCON13_POWERDNS_DISABLED=“false”


35.72.35.148 が返ってきているのはOK

https://github.com/matsuu/aws-isucon/tree/main/isucon13
を参考に確認

ベンチマークが微妙っぽい。これビルド済みだから無理かも...

おお、こんな感じでいけるっぽい

$ ./bench_linux_amd64 run –target https://pipe.u.isucon.dev
–nameserver 127.0.0.1 –enable-ssl
–webapp {サーバ2} –webapp {サーバ3}


これで見えるのか

./bench_linux_amd64 run –help




./bench_linux_amd64 run –target https://pipe.u.isucon.dev
–nameserver 127.0.0.1 –enable-ssl



./bench_linux_amd64 run –target https://pipe.u.isucon.dev –nameserver 35.72.35.148 –enable-ssl



curl -v –resolve pipe.u.isucon.dev:443:35.72.35.148 https://pipe.u.isucon.dev -k

200 OK




sudo lsof -i:53 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME pdns_serv 827 pdns 5u IPv4 17997 0t0 UDP *:domain pdns_serv 827 pdns 6u IPv6 17998 0t0 UDP *:domain pdns_serv 827 pdns 7u IPv4 17999 0t0 TCP *:domain (LISTEN) pdns_serv 827 pdns 8u IPv6 18000 0t0 TCP *:domain (LISTEN)



dig @127.0.0.1 pipe.u.isucon.dev +short 35.72.35.148 dig @35.72.35.148 pipe.u.isucon.dev +short



bench には public ip 指定が必要ぽい?
あ〜 DNS も使うから DNS のポート(UDPで)開けないとだめか

dig @35.72.35.148 pipe.u.isucon.dev +short 35.72.35.148



え〜結局証明書で落ちるのか...

{“pass”:false,“score”:0,“messages”:[“初期化が失敗しました”,“initializeのリクエストに失敗しました Post "https://pipe.u.isucon.dev:443/api/initialize": tls: failed to verify certificate: x509: certificate signed by unknown authority”],“language”:“unknown”,“resolved_count”:0}



Linux の信頼ストアは?以下っぽい? user でも追加できるっぽい

ls /etc/ssl/certs



cd /usr/share/ca-certificates/ sudo mkdir mylocal sudo cp /etc/nginx/tls/server.pem mylocal/ sudo su echo “mylocal/server.pem” » /etc/ca-certificates.conf update-ca-certificates exit



./bench_linux_amd64 run –target https://pipe.u.isucon.dev –nameserver 35.72.35.148 –enable-ssl

{“pass”:false,“score”:0,“messages”:[“初期化が失敗しました”,“initialize へのリクエストに対して、期待されたHTTPステータスコードが確認できませんでした (expected:200, actual:502)"],“language”:“unknown”,“resolved_count”:0}


証明書はOKぽいけど 502 返ってくる
サーバー側問題くさいと思う。多分 mysql 繋がってない


ps aux | grep “mysql” mysql 7268 0.1 10.8 1787920 409772 ? Ssl 01:26 1:06 /usr/sbin/mysqld isucon 63580 0.0 0.0 6612 2560 pts/1 S+ 16:18 0:00 grep –color=auto mysql



## ログは?
systemd から調べる

vi /etc/systemd/system/isupipe-go.service sudo service isupipe-go status



[Unit] Description=isupipe-go After=syslog.target After=mysql.service Requires=mysql.service

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

User=isucon Group=isucon ExecStart=/home/isucon/webapp/go/isupipe ExecStop=/bin/kill -s QUIT $MAINPID

Restart=on-failure RestartSec=5

[Install] WantedBy=multi-user.target


sudo service isupipe-go status

Main PID: 826 (code=killed, signal=TERM)

sudo service isupipe-go restart

リスタートで動作sita!



### mysql

sudo mysql isupipe show tables; +—————————-+ | Tables_in_isupipe | +—————————-+ | icons | | livecomment_reports | | livecomments | | livestream_tags | | livestream_viewers_history | | livestreams | | ng_words | | reactions | | reservation_slots | | tags | | themes | | users | +—————————-+ 12 rows in set (0.00 sec)



select * from domains; +—-+————–+——–+————+——–+—————–+———+———+———+ | id | name | master | last_check | type | notified_serial | account | options | catalog | +—-+————–+——–+————+——–+—————–+———+———+———+ | 2 | u.isucon.dev | | NULL | NATIVE | NULL | | NULL | NULL | +—-+————–+——–+————+——–+—————–+———+———+———+



やっと動いた...?


### ベンチマーク

./bench_linux_amd64 run –target https://pipe.u.isucon.dev –nameserver 35.72.35.148 –enable-ssl



livestream 動いてないっぽい?
2回目で成功

2024-11-06T16:30:51.696Z info staff-logger bench/bench.go:260 ベンチマーク走行時間: 1m0.332004691s 2024-11-06T16:30:51.697Z info isupipe-benchmarker ベンチマーク走行終了 2024-11-06T16:30:51.697Z info isupipe-benchmarker 最終チェックを実施します 2024-11-06T16:30:51.698Z info isupipe-benchmarker 最終チェックが成功しました 2024-11-06T16:30:51.698Z info isupipe-benchmarker 重複排除したログを以下に出力します 2024-11-06T16:30:51.698Z info staff-logger bench/bench.go:277 ベンチエラーを収集します 2024-11-06T16:30:51.698Z info staff-logger bench/bench.go:285 内部エラーを収集します 2024-11-06T16:30:51.699Z info staff-logger bench/bench.go:301 シナリオカウンタを出力します 2024-11-06T16:30:51.699Z info isupipe-benchmarker 配信を最後まで視聴できた視聴者数 {“viewers”: 8} 2024-11-06T16:30:51.699Z info staff-logger bench/bench.go:323 [シナリオ aggressive-streamer-moderate] 17 回成功 2024-11-06T16:30:51.700Z info staff-logger bench/bench.go:323 [シナリオ dns-watertorture-attack] 8 回成功 2024-11-06T16:30:51.700Z info staff-logger bench/bench.go:323 [シナリオ streamer-cold-reserve] 34 回成功, 2 回失敗 2024-11-06T16:30:51.701Z info staff-logger bench/bench.go:323 [シナリオ streamer-moderate] 38 回成功 2024-11-06T16:30:51.701Z info staff-logger bench/bench.go:323 [シナリオ viewer-report] 35 回成功, 2 回失敗 2024-11-06T16:30:51.701Z info staff-logger bench/bench.go:323 [シナリオ viewer-spam] 19 回成功 2024-11-06T16:30:51.702Z info staff-logger bench/bench.go:323 [シナリオ viewer] 8 回成功 2024-11-06T16:30:51.702Z info staff-logger bench/bench.go:323 [失敗シナリオ streamer-cold-reserve-fail] 2 回失敗 2024-11-06T16:30:51.702Z info staff-logger bench/bench.go:323 [失敗シナリオ viewer-report-fail] 2 回失敗 2024-11-06T16:30:51.703Z info staff-logger bench/bench.go:329 DNSAttacker並列数: 2 2024-11-06T16:30:51.703Z info staff-logger bench/bench.go:330 名前解決成功数: 1358 2024-11-06T16:30:51.703Z info staff-logger bench/bench.go:331 名前解決失敗数: 91 2024-11-06T16:30:51.704Z info staff-logger bench/bench.go:335 スコア: 2388



## DBに index 貼ってみる?
大体こういうときは mysql slow log 出すとか profiler の出番な気がするが


sudo mysql isupipe SHOW COLUMNS FROM users;


SHOW COLUMNS FROM users; +————–+————–+——+—–+———+—————-+ | Field | Type | Null | Key | Default | Extra | +————–+————–+——+—–+———+—————-+ | id | bigint | NO | PRI | NULL | auto_increment | | name | varchar(255) | NO | UNI | NULL | | | display_name | varchar(255) | NO | | NULL | | | password | varchar(255) | NO | | NULL | | | description | text | NO | | NULL | | +————–+————–+——+—–+———+—————-+


この辺見る限りえぐ目のクエリが多い?
https://github.com/isucon/isucon13/blob/main/webapp/go/top_handler.go#L75-L86

show index from users;


index は貼られてる。とってきてるデータが多いのが良くない?

https://github.com/isucon/isucon13/blob/main/webapp/go/user_handler.go
icon は static にしたいよね。AWS なら S3 + CF とかにできると嬉しいけど、そこまでじゃなくても static にしてキャッシュは効かせた方が良い


vi user_handler.go
ID だけとってくるよう変更
if err := tx.GetContext(ctx, &user, "SELECT * FROM users WHERE name = ?", username); err != nil {


sudo service isupipe-go restart sudo service isupipe-go status



### powerdns でクエリキャッシュさせる
https://ryuichi1208.hateblo.jp/entry/2022/09/12/223515

1.Authoritative Server Settings — PowerDNS Authoritative Server documentation
https://doc.powerdns.com/authoritative/settings.html


sudo vi /etc/powerdns/pdns.conf

cache-ttl=300 negquery-cache-ttl=300 query-cache-ttl=300

sudo service pdns status



## index はる

alter table themes add index idx_user_id (user_id); alter table icons add index idx_user_id (user_id);


bench してみる


## profiler 導入
これは全然わからんので、もう調査する

1.Go の pprof で ボトルネックを探して ISUCON で優勝する
https://zenn.dev/team_soda/articles/d4701665e8a3a7

そろそろ VS Code でアクセスできないとだいぶしんどいかも..

一旦次に分割する















## ISUCON11 検証
CloudFormation から立ち上げ
Bench が 1, 本番が3って構成らしい

SSH 全開放は辛いので、自分の IP 一本になるよう SG を絞る

全体構成はこんな感じ

![[../../Pasted_image_20241106101056.png]]

できれば SSM SessionManager 作った形式に書き直したいところ

と思ったら、Template 作成でエラー。image IDがないだと。。。

> なお AMI は ISUCON11 運営の解散を目処に公開を停止する予定です。上記イメージが参照不可である場合ひとつ下の手順で構築してください。



なるほど