✨
R-ISUCONN 2022 write-up
環境構築
Git
VagrantでUbuntu20.04のVMを構築しansibleを流して構築した
80番ポートをホスト:ゲストでポートフォワードすると以下のようなページが見える
初期スコア:133
isucon@ubuntu2004:~/r-isucon/bench$ ./bin/bench -target http://localhost
07:15:13.011126 Language: go
07:15:13.011282 Reason: 負荷走行に成功しました
07:15:13.011312 Score: 133
07:15:13.011315 Load Level: 1
07:15:13.011341
07:15:13.011342 Critical Error count: 0
07:15:13.011344
07:15:13.011345 Application Error count: 0
07:15:13.011347
07:15:13.011348 Trivial Error count: 0
{
"pass": true,
"score": 133,
"messages": [
"Report ID: 2a33043a-c4f9-4358-8b5e-17343d2c5884",
"負荷走行に成功しました",
"Load Level: 1"
]
}
{
"pass": true,
"score": 133,
"messages": [
"Report ID: 2a33043a-c4f9-4358-8b5e-17343d2c5884",
"負荷走行に成功しました",
"Load Level: 1"
]
}
alp / pt-query-digestの設定
- alpのインストール
wget https://github.com/tkuchiki/alp/releases/download/v1.0.12/alp_linux_amd64.tar.gz`
tar -xvf alp_linux_amd64.tar.gz
sudo install alp /usr/local/bin/alp
- alpのconfigファイル作成
isucon@ubuntu2004:~/r-isucon/bench$ cat config.yml
sort: sum # max|min|avg|sum|count|uri|method|max-body|min-body|avg-body|sum-body|p1|p50|p99|stddev
reverse: true # boolean
query_string: true # boolean
output: count,5xx,method,uri,min,max,sum,avg,p99 # string(comma separated)
matching_groups: # array
- /login
- /schedule
- /user/icon
- /calendar
- /logout
- /user
- slow query logの設定
vi /etc/mysql/mariadb.conf.d/50-server.cnf
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 0
- ログローテーション用のスクリプト作成
#!/bin/bash
# ログファイルのパス
nginx_log_path="/var/log/nginx/access.log"
mysql_log_path="/var/log/mysql/slow.log"
# ローテーション
sudo mv "$nginx_log_path" "$nginx_log_path.$(date +'%Y%m%d%H%M%S').bak"
sudo mv "$mysql_log_path" "$mysql_log_path.$(date +'%Y%m%d%H%M%S').bak"
# ログファイルの再作成
sudo touch "$nginx_log_path"
sudo touch "$mysql_log_path"
# NginxとMySQLのリスタート
sudo service nginx restart
sudo service mariadb restart
- alp結果
isucon@ubuntu2004:~/r-isucon/bench$ sudo alp ltsv --file=/var/log/nginx/access.log --config=./config.yml
+-------+-----+--------+-------------+-------+-------+---------+-------+-------+
| COUNT | 5XX | METHOD | URI | MIN | MAX | SUM | AVG | P99 |
+-------+-----+--------+-------------+-------+-------+---------+-------+-------+
| 202 | 0 | POST | /login | 0.004 | 1.688 | 107.620 | 0.533 | 1.569 |
| 658 | 0 | PUT | /schedule | 0.008 | 1.481 | 54.683 | 0.083 | 0.840 |
| 250 | 0 | GET | /calendar | 0.004 | 1.436 | 36.959 | 0.148 | 1.052 |
| 43 | 0 | POST | /user | 0.008 | 1.600 | 31.450 | 0.731 | 1.600 |
| 295 | 0 | GET | /schedule | 0.008 | 0.849 | 15.486 | 0.052 | 0.672 |
| 138 | 0 | POST | /schedule | 0.016 | 1.545 | 14.202 | 0.103 | 1.236 |
| 741 | 0 | GET | /user/icon | 0.004 | 0.540 | 10.132 | 0.014 | 0.056 |
| 1026 | 0 | GET | /user | 0.000 | 0.584 | 5.526 | 0.005 | 0.020 |
| 114 | 0 | GET | /me | 0.004 | 0.140 | 1.124 | 0.010 | 0.108 |
| 228 | 0 | POST | /logout | 0.000 | 0.100 | 0.714 | 0.003 | 0.020 |
| 1 | 0 | POST | /initialize | 0.184 | 0.184 | 0.184 | 0.184 | 0.184 |
| 4 | 0 | PUT | /me/icon | 0.044 | 0.061 | 0.157 | 0.039 | 0.061 |
| 3 | 0 | PUT | /me | 0.012 | 0.016 | 0.028 | 0.009 | 0.016 |
+-------+-----+--------+-------------+-------+-------+---------+-------+-------+
→まずは最も遅いPOST /login を改善する
POST /loginの改善:(133->313)
login時のセッションID生成のコードの効率が悪いため改善する
isucon@ubuntu2004:~/r-isucon/bench$ ulimit -u 1024 && ./bin/bench -target http://localhost
07:32:34.256547 Language: go
07:32:34.256569 Reason: 負荷走行に成功しました
07:32:34.256578 Score: 313
07:32:34.256580 Load Level: 1
07:32:34.256584
07:32:34.256585 Critical Error count: 0
07:32:34.256587
07:32:34.256588 Application Error count: 0
07:32:34.256593
07:32:34.256594 Trivial Error count: 0
{
"pass": true,
"score": 313,
"messages": [
"Report ID: 58972996-df74-4eb8-a308-62c9164a501f",
"負荷走行に成功しました",
"Load Level: 1"
]
}
{
"pass": true,
"score": 313,
"messages": [
"Report ID: 58972996-df74-4eb8-a308-62c9164a501f",
"負荷走行に成功しました",
"Load Level: 1"
]
}
isucon@ubuntu2004:~/r-isucon/bench$ sudo alp ltsv --file=/var/log/nginx/access.log --config=./config.yml
+-------+-----+--------+-------------+-------+-------+---------+-------+-------+
| COUNT | 5XX | METHOD | URI | MIN | MAX | SUM | AVG | P99 |
+-------+-----+--------+-------------+-------+-------+---------+-------+-------+
| 531 | 0 | GET | /calendar | 0.004 | 5.281 | 116.634 | 0.220 | 0.752 |
| 971 | 0 | PUT | /schedule | 0.020 | 6.175 | 58.911 | 0.061 | 0.124 |
| 653 | 0 | GET | /schedule | 0.012 | 0.268 | 21.808 | 0.033 | 0.068 |
| 253 | 0 | POST | /schedule | 0.024 | 6.091 | 18.558 | 0.073 | 0.332 |
| 2165 | 0 | GET | /user | 0.004 | 4.730 | 17.447 | 0.008 | 0.012 |
| 1425 | 0 | GET | /user/icon | 0.004 | 0.236 | 9.190 | 0.006 | 0.028 |
| 404 | 0 | POST | /login | 0.000 | 1.435 | 2.868 | 0.007 | 0.012 |
| 43 | 0 | POST | /user | 0.008 | 0.052 | 0.782 | 0.018 | 0.052 |
| 200 | 0 | GET | /me | 0.004 | 0.020 | 0.720 | 0.004 | 0.016 |
| 424 | 0 | POST | /logout | 0.000 | 0.008 | 0.493 | 0.001 | 0.008 |
| 1 | 0 | POST | /initialize | 0.204 | 0.204 | 0.204 | 0.204 | 0.204 |
| 5 | 0 | PUT | /me | 0.008 | 0.020 | 0.060 | 0.012 | 0.020 |
| 3 | 0 | PUT | /me/icon | 0.028 | 0.032 | 0.060 | 0.020 | 0.032 |
+-------+-----+--------+-------------+-------+-------+---------+-------+-------+
→GET /calendarが遅くなるのでこちらを改善する
GET /calendarの改善:(313->657)
GET /calendarは会議参加者の存在有無を全アクセスに対して行っているが
無駄であるため、プログラム内のmapにキャッシュさせる。
この修正をいれるとアクセス数が増えnginxのファイルディスクリプタ数不足のエラー
が出たので以下の修正も入れた。
isucon@ubuntu2004:~/r-isucon/bench$ ulimit -u 1024 && ./bin/bench -target http://localhost
17:04:56.450093 負荷レベルが上昇しました
17:05:16.263116 Language: go
17:05:16.263134 Reason: 負荷走行に成功しました
17:05:16.263139 Score: 657
17:05:16.263141 Load Level: 2
17:05:16.263142
17:05:16.263144 Critical Error count: 0
17:05:16.263145
17:05:16.263146 Application Error count: 0
17:05:16.263148
17:05:16.263149 Trivial Error count: 0
{
"pass": true,
"score": 657,
"messages": [
"Report ID: ccf4247a-ca2c-41cd-9f0e-230fa63ceaef",
"負荷走行に成功しました",
"Load Level: 2"
]
}
{
"pass": true,
"score": 657,
"messages": [
"Report ID: ccf4247a-ca2c-41cd-9f0e-230fa63ceaef",
"負荷走行に成功しました",
"Load Level: 2"
]
}
isucon@ubuntu2004:~/r-isucon/bench$ sudo alp ltsv --file=/var/log/nginx/access.log --config=./config.yml
+-------+-----+--------+-------------+-------+-------+--------+-------+-------+
| COUNT | 5XX | METHOD | URI | MIN | MAX | SUM | AVG | P99 |
+-------+-----+--------+-------------+-------+-------+--------+-------+-------+
| 1313 | 0 | GET | /calendar | 0.004 | 4.704 | 88.386 | 0.067 | 0.164 |
| 1423 | 0 | GET | /schedule | 0.012 | 4.760 | 85.522 | 0.060 | 0.124 |
| 926 | 0 | PUT | /schedule | 0.020 | 4.756 | 81.939 | 0.088 | 0.432 |
| 433 | 0 | POST | /schedule | 0.008 | 4.736 | 42.884 | 0.099 | 1.724 |
| 2844 | 0 | GET | /user/icon | 0.004 | 4.700 | 34.385 | 0.012 | 0.056 |
| 5286 | 0 | GET | /user | 0.000 | 3.796 | 23.250 | 0.004 | 0.012 |
| 817 | 0 | POST | /login | 0.004 | 0.044 | 2.995 | 0.004 | 0.020 |
| 438 | 0 | GET | /me | 0.004 | 0.028 | 1.661 | 0.004 | 0.024 |
| 75 | 0 | POST | /user | 0.004 | 0.052 | 1.519 | 0.020 | 0.052 |
| 841 | 0 | POST | /logout | 0.000 | 0.016 | 1.042 | 0.001 | 0.008 |
| 16 | 0 | PUT | /me/icon | 0.020 | 0.072 | 0.472 | 0.030 | 0.072 |
| 1 | 0 | POST | /initialize | 0.136 | 0.136 | 0.136 | 0.136 | 0.136 |
| 11 | 0 | PUT | /me | 0.001 | 0.016 | 0.113 | 0.010 | 0.016 |
| 5 | 0 | GET | /api/me | 0.000 | 0.004 | 0.008 | 0.002 | 0.004 |
+-------+-----+--------+-------------+-------+-------+--------+-------+-------+
→まだ/calendarが一番遅いが、同じくらい遅い/sheculeの改善に移ってみる
GET /scheduleの改善:(657 -> 925)
GET /scheduleの中でorecocoReserveへsheduleのmeeting roomの状況を
問い合わせているが、同じsheduleの状況についてはキャッシュできるため
r-calendar側にsheculeID毎のmeeting roomの状況をキャッシュさせる。
isucon@ubuntu2004:~/r-isucon/bench$ sudo alp ltsv --file=/var/log/nginx/access.log --config=./config.yml
+-------+-----+--------+-------------+-------+-------+--------+-------+-------+
| COUNT | 5XX | METHOD | URI | MIN | MAX | SUM | AVG | P99 |
+-------+-----+--------+-------------+-------+-------+--------+-------+-------+
| 1944 | 0 | GET | /schedule | 0.016 | 1.416 | 90.447 | 0.047 | 0.252 |
| 1172 | 0 | PUT | /schedule | 0.024 | 2.572 | 80.152 | 0.068 | 0.284 |
| 1803 | 0 | GET | /calendar | 0.004 | 1.800 | 54.586 | 0.030 | 0.116 |
| 3905 | 0 | GET | /user/icon | 0.004 | 0.992 | 43.085 | 0.011 | 0.048 |
| 602 | 0 | POST | /schedule | 0.004 | 2.596 | 39.151 | 0.065 | 0.460 |
| 6802 | 0 | GET | /user | 0.004 | 0.816 | 27.386 | 0.004 | 0.012 |
| 1125 | 0 | POST | /login | 0.004 | 1.696 | 6.689 | 0.006 | 0.020 |
| 574 | 0 | GET | /me | 0.004 | 0.072 | 2.464 | 0.004 | 0.028 |
| 76 | 0 | POST | /user | 0.004 | 0.064 | 1.896 | 0.025 | 0.064 |
| 1145 | 0 | POST | /logout | 0.000 | 0.016 | 1.536 | 0.001 | 0.012 |
| 16 | 0 | PUT | /me/icon | 0.008 | 0.404 | 0.908 | 0.057 | 0.404 |
| 17 | 0 | PUT | /me | 0.008 | 0.036 | 0.248 | 0.015 | 0.036 |
| 1 | 0 | POST | /initialize | 0.136 | 0.136 | 0.136 | 0.136 | 0.136 |
| 3 | 0 | GET | /api/me | 0.004 | 0.004 | 0.004 | 0.001 | 0.004 |
+-------+-----+--------+-------------+-------+-------+--------+-------+-------+
残課題
- r-calendarにorecoco-reserveの機能を統合する
- DBサーバとAPサーバを分離する
Discussion