---
# System prepended metadata

title: ISUCON11の自分用メモ

---

# 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))
	}()
```
