issues
search
wantedly
/
shisucon2019-teppei-haruki
SHInsotsu iSUCON
2
stars
0
forks
source link
よくやる施策
#2
Open
euglena1215
opened
5 years ago
euglena1215
commented
5 years ago
一旦何も考えずに書き出してみてあとでまとめる
euglena1215
commented
5 years ago
indexを貼る
DBのCPU使用量対策
N+1クエリの修正
DBのCPU使用量対策
レコード数が100に満たないような小さなテーブルだとそこまで気にしなくていいことがある
秘伝のたれ流し込み
諸々対策、型がはまれば劇的な改善が見込める
静的ファイル配信のキャッシュ化
ネットワーク帯域対策、ここやってないとこのボトルネックが支配的すぎて他のボトルネックが見えないので早急に対応する必要あり
最初のブレイクスルーになりがち
諸々のworker数、process数の調整
一通りの改善が済んでからでも問題ない、worker数を上げるのは負荷をあげてスループットを上げる行為なのでそれなりに高速化してないと意味ない
unix domain socketに変更
なんか早くなる気がする
redisに載せる
キャッシュに載せることができたらDBアクセスが減って大幅な改善が見込める。
ただ、ハイリスクハイリターンな施策(時間はかかるが、うまくいくとブレイクスルーがある)なので「正しくindexを貼る」「直せそうなN+1はきちんと直す」「マスターデータはグローバル変数に置く」などをやった上で行う
処理のオーダーを落とす(メモ化、hashをうまく使うなど)
アプリのCPU負荷を下げるのに有効、ちょこっとメモリも節約できるかも
mysqlのconnectionを使い回す
connectionのオーバーヘッドを下げるため
statement.close忘れ探し
たまに忘れている。気をつける
kill ORDER BY RAND() LIMIT N
RAND()にはindexが貼られてないので遅い。ここはアプリケーション側でいい感じに実装した方がよいこともある。
そんなに効かないのでやるとしても中盤かなという印象
画像データをDBから抜き出す
静的ファイル配信するために必須。最速で行う
transactionを可能な範囲まで狭める
DBのロック待ちを短くするのが目的
これの見極め難しいので中盤かな
テーブルロックを行ロックにできないか考える
多分新しくtableを作るとかしないといけないので結構大変。時間内になるのは難しいかも。
ただ、ロック待ちがボトルネックの場合はブレイクスルーになる
微妙な共通化がされていて読みにくいときは共通化を剥がす
微妙にメソッド化されてるとN+1を直しにくかったりするので剥がしてしまうのが吉。
直接高速化には繋がらないけど重要
viewでSQLが実行されてないか調べる
たまにviewでSQL実行してたりして見落とすことがあるのでちゃんと確かめる
グローバル変数化
INSERTが走らないデータはグローバル変数として持ってオンメモリ化してしまう方がよい
メモリがカツカツであればやらない方がよい可能性もある
*を消す
クエリが早くなるというよりもメモリに載せるデータが小さくなる方が嬉しみポイント
ただ、covering indexが効くような場合だとそれなりに早くなる場合もある
DBに処理を任せる
COUNTなどはアプリケーションでやるよりDBでやった方が早い場合が結構ある。メモリを圧迫しないのも嬉しい。
正しくindexが貼られたDBは結構早い。
メモリリークに気をつける
pumaを一定時間起動しているとなぜかメモリをめっちゃ食ってるときがある。
puma-killer的なやつを導入して定期的に殺してもらうようにする
LIMIT OFFSETをBETWEENに置き換える
レコード数の多いテーブルの場合、LIMIT OFFSETよりもBETWEENの方が早いケースがある。
ORDER BYで複雑なことをしていたらBETWEENで表現できない場合もあるので考える
可能であればINで指定して取れるのが一番早い
indexがどうやって作られるか確認する
場合によってはbenchが走る度に所定のsqlが実行されtableが作られる、という年がありmysqlのconsoleに入って貼ったindexが全く機能していないというアクシデントがあったのできちんと確認する
[夢] rubyを2.6にする
基本的にバージョンアップしたら効率よくなるのでやることなくなったら試してみたい
[夢] mysqlを8.0にする
たぶん壊れるので複数台構成で残機があれば試せる。多分壊れる。
複数台をうまく使う
結構問題による。1台DB、2台アプリケーションとかが定番。
一番単純なのが①DB ②web(nginx)+App ③Appでラウンドロビン
画像の更新系endpointは複数台にすると画像の同期が必要になって大変になるので1台のみで受け付けるようにする、
どうしても解決できないN+1があるときはそのendpointだけDBサーバに同居させて通信時間をなるべく短くする、
CSV作成といっためちゃメモリ食うやつだけ特定のサーバにする、みたいな感じでまじで場合による、
CPU・メモリ・ネットワーク帯域とにらめっこするしかなさそう
euglena1215
commented
5 years ago
@spring1018
indexを貼る
indexがどうやって作られるか確認する
N+1クエリの修正
処理のオーダーを落とす(メモ化、hashをうまく使うなど)
微妙な共通化がされていて読みにくいときは共通化を剥がす
グローバル変数化
viewでSQLが実行されてないか調べる
この辺がカバーできてるとありがたいかな、という気持ちです!
一旦何も考えずに書き出してみてあとでまとめる