# ISUCON11の自分用メモ ### 心構え編 どうせ当日には全て忘れるけど - 基本的な部分の解消がテンポよくできれば予選は突破できる(と思う) - 本質的な改善を先に(最初から安易にmemcacheに走らない) - alp -> pprofを見る - まずは全体で遅い箇所->Appで対応が必要な箇所 - 改善できたからと言って点数が伸びるとは限らない - 複数ボトルネックを解消する必要がある - 改善できたかどうかは点数ではなくchromeのnetworkタブのレスポンス速度で確認すべし - 速度=点数ではない場合があるので当日マニュアルをよく読もう - 修正する箇所は関数に分割しよう - すぐに戻れるように - コメントを書いてコードを理解しよう - 概要把握が大切 - ローカルで動作させられるようにしよう - 時間をかけても大丈夫 - 最初の1~2時間はこちらに集中してもいいくらい - mysqlにデータが入ればクエリ書き放題 - 2~3台目で練習もあり - 大きいボトルネックは簡単な改善を積み重ねていく - N+1はまずは複数回クエリを発行しているところを全取得->app側で処理に変えてみる - その後に効率よく解決していけばいい - リクエストが見られるならリスポンスをみよう - 実装後に再度叩いてみて同じレスポンスが帰ってくるか確認する - 速度は変わっているかどうか確認する - 余裕があればテストを書く ### 具体的行動編 #### 考えるべき箇所 - メモリ - 帯域 - ディスクI/O - フロントエンドCache(nginxでpublicつけるといけるらしい) #### 再起動対策 - DBにはpingで問い合わせる - openは参照のみなので注意 #### MySQLのデータの内容を確かめる https://qiita.com/ikenji/items/b868877492fee60d85ce - rows数が多いいテーブルをselect * from hogeしていないか - memoryに載せるならサイズは大丈夫か DBのサイズ ```sql= SELECT table_schema, sum(data_length) /1024/1024 AS mb FROM information_schema.tables GROUP BY table_schema ORDER BY sum(data_length+index_length) DESC; ``` Tableのサイズ ```sql= SELECT table_name, engine, table_rows AS tbl_rows, avg_row_length AS rlen, floor((data_length)/1024/1024) AS dmb, floor((index_length)/1024/1024) AS imb FROM information_schema.tables WHERE table_schema=database() ORDER BY (data_length+index_length) DESC; ``` #### どんなクエリが書かれているか確かめる https://github.com/tenntenn/isucontools queryを出してくれる masiくんがN+1を調べてくれる みるべきはupdateとinsertが走っているテーブル それ以外は不変なので楽にキャッシュができる(再起動のやつ注意) #### top メモリやCPU使用量をみる top -s 4 とか良さそう memoryは top -s 1 -o mem でソートできるそう ### 余計なこと編 - httpsならhttp2, http3にすることで高速化できる ### コード編 再起動対策 ```go= dsn := fmt.Sprintf( "%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=true&loc=Local", user, password, host, port, dbname, ) dbx, err = sqlx.Open("mysql", dsn) if err != nil { log.Fatalf("failed to connect to DB: %s.", err.Error()) } defer dbx.Close() for { err := dbx.Ping() if err == nil { break } log.Println(err) time.Sleep(time.Second * 1) } ``` pprof ```go= import ( _ "net/http/pprof" ) go func() { log.Println(http.ListenAndServe("0.0.0.0:6060", nil)) }() ```