最近の砂場活動その6: パフォーマンスを改善する

最近は登壇とかでエネルギーを取られて、砂場活動シリーズ(?)全然できていませんでした。せっかく前期に砂場を作ったので、勉強の場にしていきます。現状のボトルネックがどこにあって、どこを改善していきましょう、というループを回します。ISUCONとかやってる人には当たり前のことばかりだと思うけど、その辺あまり慣れていないのでぼちぼちとやっていきます。派手なことななく地味にやっていく。

現状を知る

改善をするためには現状のパフォーマンスを知ることが重要です。趣味サイトはユーザーが自分しかいないので、ベンチマークスクリプトをかけてパフォーマンスを見ていきます。スプレッドシートにまとめていくのは面倒だったので、Mackerelのプラグインを書いて可視化しました。

改善していく中でRDS/ElastiCacheのCPU/メモリ/コネクション数/トラフィック量などが一目で分かるようなダッシュボードも作りました。結果ではなく原因になった場所がどこかを調べるのに便利。

数値だけ見ても分からないことも多いので、CloudWatch LogsにアプリやNginxのログを流すように設定。

あれこれ改善

自分しか使っていないとアホなことをやっていても問題にならないけど、ベンチマークを回すとそういったところが問題点になってくるので改善していく。

  • fullscanが走っているところにDBにインデックスを張る
  • コネクションプールを使い回す
  • N+1を潰す
    • 潰しましょう
  • Redisのパイプラインを使う
    • 1つずつコマンドを送るのではなくまとめてやれる方法
  • 必要なフィールドのみ取得するようにする
    • 特徴量やhtmlもredisに雑に放り込んで学習時には使っていたけど、apiのレスポンスを返すときには使っていない(SELECT *的なことになっていた)
    • 結構巨大なフィールドなので、不必要なものは削って必要なものだけ返すようにする
    • jsonとしてredisのvalueに放り込んでたけど、取ってくるフィールドを選択できるようにハッシュ型に変更した
    • https://github.com/syou6162/go-active-learning/pull/31
  • アプリケーションサーバーやDBのリソースは余ってるけど、レイテンシーが悪化するようになってきた
    • ちょっと悩んでしまったけど、負荷試験をされる側ではなくて負荷試験をする側のネットワーク帯域がボトルネックになっていた
    • 負荷試験を複数のインスタンス(Fargate)から実行するようにして負荷分散
  • goroutineでtoo many open files
  • nginxでToo many open files
    • 何やねんと思ったけど、ファイルディスクリプタの上限に引っかかってしまっていた
    • Fargateで動かしている場合も変更できるので増やした

次回

この辺までやるとあとはFargateの数増やしたり、ElastiCache/RDSのスペックを上げたり、リードレプリカの台数を増やせば捌けるリクエスト数も増やしていけそうなかという目処が立ってきた。次回作にご期待ください。

負荷試験をしていたら順調にAWSへの課金額も伸びてきた😇。

理論から学ぶデータベース実践入門 ~リレーショナルモデルによる効率的なSQL (WEB+DB PRESS plus)

理論から学ぶデータベース実践入門 ~リレーショナルモデルによる効率的なSQL (WEB+DB PRESS plus)