ãã®è¨äºã¯ã¯ã¦ãªã¨ã³ã¸ã㢠Advent Calendar 2023ã®17æ¥ç®ã®è¨äºã§ãã
ã¤ãã§ã«ISUBONã®17æ¥ç®ã®è¨äºã§ããã¹ã³ã¢ã¯å¤ããã717,858ç¹ã
ä»æã®åãããISUBON(Iikanjini Speed Up BlogathON)ã¨ç§°ãã¦private-isuã§éãã§ãããã«ã¼ã«ã¯ä»¥ä¸ã®éãã
- æ¯æ¥24æã¾ã§ã«ç¶ç¶æ¥æ°x10,000以ä¸ã®ã¹ã³ã¢ãåºã
- æ¯æ¥24æã¾ã§ã«ãã®æ¥ãã£ããã¨ã®ããã°ãæ稿ãã
- 以ä¸ã®ã©ã¡ããã«å¤±æãããçµãã
æ¨æ¥ã¾ã§ã§717,858ç¹åããã®ã§ãã®ããã«ãã£ããã¨ãã¾ã¨ããã
ãªãã¸ããª: https://github.com/Gurrium/private-isu
追è¨ï¼80ä¸ç¹éæãã
25日目, 814,586 - ぜのぜ
追è¨ï¼90ä¸ç¹éæãã
26日目, 916,936 - ぜのぜ
追è¨ï¼100ä¸ç¹éæãã
28日目, 1,012,219 - ぜのぜ
ç°å¢
- 競æç¨ã¤ã³ã¹ã¿ã³ã¹: c6i.large
- ãã³ããã¼ã«ã¼ç¨ã¤ã³ã¹ã¿ã³ã¹: c6ixlarge
è¨æ¸¬
MySQL
ã¹ãã¼ã¯ã¨ãªã®ãã°
[mysqld] slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 0
https://github.com/Gurrium/private-isu/blob/main/webapp/etc/my.cnf
nginx
log_format json escape=json '{' '"time":"$time_iso8601",' '"method":"$request_method",' '"uri":"$request_uri",' '"status":"$status",' '"body_bytes":"$body_bytes_sent",' '"request_time":"$request_time",' '"response_time":"$upstream_response_time"' '}'; server { access_log /var/log/nginx/access.log json; }
https://github.com/Gurrium/private-isu/blob/main/webapp/etc/nginx/conf.d/default.conf
Go
pprof
import _ "net/http/pprof" func main() { runtime.SetBlockProfileRate(1) runtime.SetMutexProfileFraction(1) go func() { log.Fatal(http.ListenAndServe(":6060", nil)) }() }
https://github.com/Gurrium/private-isu/blob/main/webapp/go/app.go
ã¹ã¯ãªãã
ãããã¤
#!/bin/sh # referenced from https://github.com/tatsuru/isucon13/blob/main/scripts/deploy set -v now=$(date +%Y%m%d-%H%M%S) branch=${1-main} update="cd /home/isucon/private-isu && git remote update && git checkout $branch && git pull" restart="cd /home/isucon/private-isu/webapp/go && /home/isucon/.local/go/bin/go build -o app && sudo systemctl restart isu-go" rotate_mysql="sudo mv -v /var/log/mysql/slow.log /var/log/mysql/slow.log.$now && mysqladmin -uisuconp -pisuconp flush-logs" rotate_nginx="sudo mv -v /var/log/nginx/access.log /var/log/nginx/access.log.$now && sudo systemctl reload nginx" git push origin $branch ssh isucon@privateisup "$update && $restart && $rotate_mysql && $rotate_nginx"
https://github.com/Gurrium/private-isu/blob/main/webapp/scripts/remote/deploy
解æ
#!/bin/sh set -v now=$(date +%Y%m%d-%H%M%S) analyze_access="sudo alp json --file /var/log/nginx/access.log -r --sort=avg -m \"/image/[0-9]+.(jpg|png|gif), /@[a-zA-Z]+, /posts/[0-9]+\"" analyze_slow_query="sudo pt-query-digest /var/log/mysql/slow.log" ssh isucon@privateisup "$analyze_access" | tee logs/nginx/digest.log.$now ssh isucon@privateisup "$analyze_slow_query" | tee logs/mysql/digest.log.$now rsync -v isucon@privateisup:/home/isucon/profile.pb.gz logs/pprof/profile.pb.gz.$now go tool pprof -http=localhost:6060 logs/pprof/profile.pb.gz.$now
https://github.com/Gurrium/private-isu/blob/main/webapp/scripts/remote/analyze
ãã³ããã¼ã¯
æ¬çªã§ã¯ãã¼ã¿ã«ããã ãã©pprofã®ä½¿ãæ¹ã®ã¡ã¢ã¨ãã¦ã
#!/bin/sh set -v pprof="/home/isucon/.local/go/bin/go tool pprof -proto -seconds 60 -output profile.pb.gz http://localhost:6060/debug/pprof/profile" benchmark="/home/isucon/private_isu.git/benchmarker/bin/benchmarker -u /home/isucon/private_isu.git/benchmarker/userdata -t http://privateisup" ssh isucon@privateisup "$pprof" & ssh isucon@privateisub "$benchmark"
https://github.com/Gurrium/private-isu/blob/main/webapp/scripts/remote/benchmark
æ¹å
ã¤ã³ããã¯ã¹
ã¹ãã¼ã¯ã¨ãªãè¦ãã«å¿ è¦ãããªã«ã©ã ã«ä¸éãè²¼ã£ãã
N+1ã®è§£æ¶
åæç¶æ
*1ã§ã¯äºéã«N+1ãèµ·ãã¦ããããã³ã¡ã³ãã¨ã¦ã¼ã¶ã¼ä¸¡æ¹ã§N+1ãèµ·ãã¦ãããããã®ã§ã§ããã¨ãããã解ãã»ãããã
ç¾æç¹ã§ãå®å
¨ã«ã¯è§£æ¶ã§ãã¦ãªããããã£ãã·ã¥ã¨çµã¿åãããããä¸æ¦å
¨é¨å¼ãã¦ãã¦ã¡ã¢ãªä¸ã§å
¥ãæ¿ããããã¦å½±é¿ãæãã¦ããã
https://github.com/Gurrium/private-isu/blob/ebe2728de17cea7b7286f1fc2cecccc6fd0b0e06/webapp/go/app.go#L195-L352
DBã«ãããã¼ã¿ã®ãã£ãã·ã¥
ã»ãã·ã§ã³å¨ãã®ã¦ã¼ã¶ã¼ã®ãã¼ã¿ã¨æ稿ã®ãã¼ã¿ãªã©ããã£ãã·ã¥ãããã¨ã³ã³ã¼ãã«ä½¿ãã©ã¤ãã©ãªã¯encoding/jsonããsonnet*2ã«å¤ããã
ä»åã¯ãµã¼ãã¼ã1å°ã ããªã®ã§memcachedã¯ããããããã ãã§ãçµæ§æ©ããªãã
https://github.com/Gurrium/private-isu/commit/b7d5b21f5526e734e3886e639011a3b8b6fec43e
追è¨ï¼ãã£ãã·ã¥ç¨ã®ã©ã¤ãã©ãªã使ããmap
ã§ç®¡çããä»çµã¿ãèªåã§ä½ã£ã¦ä½¿ãã®ãä¸çªæ©ãã£ããã©ã¤ãã©ãªã¯ãã¤ããªã«ããã¡ã§encode, decodeãçµæ§éãã
éçãã¡ã¤ã«ã®é ä¿¡
nginxããè¿ãããã«ãããã¯ã©ã¤ã¢ã³ãã«ãã£ãã·ã¥ããããã
https://github.com/Gurrium/private-isu/pull/3/commits/0f67875f5fbfa72f442733ba80640c4c8bde7a98
å¤é¨ã³ãã³ãããã©ã¤ãã©ãªã¸ã®å¤æ´
ããã·ã¥ãè¨ç®ããã®ã«å¤é¨ã³ãã³ãã使ã£ã¦ããã®ã§ã©ã¤ãã©ãªã«ç½®ãæããã
https://github.com/Gurrium/private-isu/commit/2a397bb9736d6c67fecc397ba67aacfb02ad7f22
fmt.Sprintf
ã®çµæã®ä½¿ãåã
è¦åºãããã«ãã¿åºãã»ã³ãNo.1ãruntime.growslice
ã¨ä¸ç·ã«æ½°ããã®ã§æ£ç¢ºãªå¹æã¯åãããªãããpprofã§è¦ãã¨çµæ§æéãããã£ã¦ããã®ã§ããããå¹ãã¦ããã®ã§ã¯ãªããã
https://github.com/Gurrium/private-isu/commit/4c3e9600211a74df59a601219e9c247d7bd592c1
runtime.growslice
æ²æ»
å¿
è¦ãªsliceã®å¤§ãããããã£ã¦ããã¨ãã¯åæåæã«ç¢ºä¿ããã
https://github.com/Gurrium/private-isu/commit/4c3e9600211a74df59a601219e9c247d7bd592c1
MySQLã®è¨å®ã®èª¿æ´
æ¸ãè¾¼ã¿
https://github.com/Gurrium/private-isu/pull/4/commits/6b6192f656a8dfb9edda76f7c42e689485059d01
interpolateParams=true
https://github.com/Gurrium/private-isu/commit/361772edde7d31e21b7a5ef5d80455176362684a
html/templateè±åº
ãã³ãã¬ã¼ãã®å¦çã«æéãããã£ã¦ããã®ã§ææ¸ãããã
https://github.com/Gurrium/private-isu/pull/4/commits/a55dad2a01f5ff7286c41f02402691fb00937a81
æååã®çµåã¯é
ãã®ã§ã¬ã¹ãã³ã¹ãæååã§çµã¿ç«ã¦ãã®ã§ã¯ãªãç´æ¥http.ResponseWriter
ã«æ¸ãè¾¼ããæ¸ãè¾¼ãå¤ãéçã«æ±ºã¾ããã®ã¯èµ·åæã«ãã¤ãåã«å¤æãã¦ããã¦ä½¿ãåãã¨runtime.newobject
ãæ¸ãããã
https://github.com/Gurrium/private-isu/blob/ebe2728de17cea7b7286f1fc2cecccc6fd0b0e06/webapp/go/app.go#L667-L789
ç»åã®é ä¿¡å ã®å¤æ´
DBãããã¡ã¤ã«ã«å¤ãããDBãããã¡ã¤ã«ã¸ã®æ¸ãåºããåæåå¦çã«æ¸ãã¨æéããããããã¦å¤å失æå¤å®ãããã®ã§ãåãã¦ãªã¯ã¨ã¹ããæ¥ãã¨ãã«ãããæ°è¦ã®ç»åã¯ç´æ¥ãã¡ã¤ã«ã«ä¿åãããæç§æ¸éãã
ãªã¯ã¨ã¹ãããããã¹ã¯/image/\d+
ã ãããã¡ã¤ã«ã®ãã¹ã¯/public/img/\d+
ã§ããããã®å ´åã¯aliasã使ãã°ããã¨æ°ã¥ãã®ã«çµæ§æéãããã£ãã
https://github.com/Gurrium/private-isu/pull/3/commits/e20569e2e37ad698e37c91c9ff9f8b7049cc6b81
è«çåé¤ã®å¦çã®å¤æ´
0 or 1ã®ãã©ã°ã§0ãã»ã¨ãã©ãªã®ã§ã¤ã³ããã¯ã¹ãè²¼ã£ã¦ã大ãã¦å¹çããããªããªãã£ããã¡ã¢ãªã«è«çåé¤ãããã¦ã¼ã¶ã¼ã®IDãæã£ã¦ã¯ã¨ãªã«æ¸¡ãããã«ããã
https://github.com/Gurrium/private-isu/commit/b9ea89a04be2822aa33ff6e5f328767120caa072
ã³ã¡ã³ãæ°ã®ä¿å
COUNT(*)
ã¯çµæ§éãå¦çã®ããã ã£ãã®ã§ã«ã©ã ã«æã¤ããã«ããã
https://github.com/Gurrium/private-isu/commit/d2c8d452179bafb243545c3f257f562854d06443