振り返りと、残っているもの
読了目安 約3分
7 倍までの道のりを一覧で確認し、まだ手をつけていない場所を見ます。
この章の目次
スコアの推移
| 何をしたか | スコア | 前回比 |
|---|---|---|
| 初期実装 | 6072 | — |
| インデックスを足した | 10319 | +70 % |
| ランキングの N+1 を消した | 10434 | +1 % |
| 参加者詳細の N+1 を消した | 10105 | −3 % |
| CSV 入稿をまとめた | 35888 | +255 % |
| 取る量を減らした | 38522 | +7 % |
| 公開鍵・Debug・Logger | 41693 | +8 % |
| テナントの引き直しをやめた | 44139 | +6 % |
大きく動いたのは 2 回だけです。 インデックスと、CSV 入稿の書き込みをまとめたところです。
どちらも、計測が回数や行数の異常を指していた場所でした。 一方、コードだけ読んで「これは N+1 だ」と判断した回は動きませんでした。
いまのアクセスログ
+-------+--------+-------------------------------------------+-------+-------+----------+
| COUNT | METHOD | URI | AVG | MAX | SUM |
+-------+--------+-------------------------------------------+-------+-------+----------+
| 22642 | GET | /api/player/player/[^/]+ | 0.075 | 1.381 | 1693.848 |
| 10011 | GET | /api/player/competition/[^/]+/ranking | 0.102 | 1.344 | 1017.992 |
| 36 | POST | /api/organizer/players/add | 2.371 | 9.257 | 85.341 |
| 145 | GET | /api/admin/tenants/billing | 0.519 | 8.773 | 75.235 |
| 219 | GET | /api/organizer/billing | 0.327 | 3.969 | 71.587 |
+-------+--------+-------------------------------------------+-------+-------+----------+参加者の詳細は、平均 0.594 秒から 0.075 秒になりました。 同じ 60 秒で捌けた件数は 1987 件から 22642 件です。
残っているもの
参加者の追加が 1 件 2.4 秒
for _, displayName := range displayNames {
id, err := dispenseID(ctx)
if err != nil {
return fmt.Errorf("error dispenseID: %w", err)
}
// 1人ずつ INSERT
}第 5 章で見たものと同じ形です。
参加者 1 人ごとに MySQL へ書きに行き、1 人ごとに INSERT しています。
請求レポートが大会ごとに集計している
/api/organizer/billing は、テナント内の大会を 1 つずつ回して集計します。
大会ごとにファイルロックを取り、MySQL と SQLite に 1 クエリずつ投げています。
大会が終了していれば、請求額はもう変わりません。 終了時に計算して保存しておけば、参照は取り出すだけになります。
データの置き場所そのもの
アプリが使う CPU の 4 割は、SQLite の行読み出しです。 テナント DB を MySQL に寄せると、この形は根本から変わります。
ただし、テナントの数だけあるファイルを 1 つのデータベースに移す作業です。 時間が残っているかどうかで判断が変わります。
1 台で足りているか
いまはアプリ・MySQL・nginx が同じ 1 台に載っています。 2 コアの平均使用率が 6 割、ピークで 9 割です。 その内訳はアプリが 0.78 コア、MySQL が 0.39 コアです。
Part 8 で見たとおり、分けるかどうかは、分けたあとに何が起きるかを見積もってから決めます。
この Part でやったこと
- 走らせて、アクセスログとスロークエリログを集計する
- 合計時間の上位と、回数や行数が異常なクエリを探す
- 直す場所を 1 つ決めて、直して、また走らせる
- 効かなかったら粘らずに計測へ戻る
- ログに出ない処理は pprof で見る
順番はこれだけです。 どの問題でも変わりません。
過去問はほかにもあります。 Part 6 に挙げた素振りのやり方で、次の問題に同じ手順を当ててみてください。