はじめに
- 業務で、DBとAPIサーバのパフォーマンスチューニングを行う予定なのですが、全く行ったことがなかったので、どのような手順や方法で進めていくのか調べてみました。
目次
- パフォーマンスチューニングとは
- パフォーマンスチューニングの種類
- SQLチューニング
- indexチューニング
- auroraについて
- APIサーバ側のチューニングについて
1. パフォーマンスチューニングとは
パフォーマンスチューニングの説明として、一番しっくりきました。
システムの処理性能や信頼性を高めるために,システムの動作環境を最適化することです。パフォーマンスチューニングを実施することで,システムの性能を最大限に生かし,安定稼働させられるようになります。
一般的には、SQLやDBのチューニング
を指しているようでした。
パフォーマンスチューニング ≒ SQLやDBのチューニング
2. パフォーマンスチューニングの種類
今回は、バックエンド側のみです。主なパフォーマンスチューニングは、以下の通りでした。
SQLチューニング
DBチューニング
APIサーバ側のチューニング
具体的には、以下のようなチューニングを行うことが可能です。
SQLチューニング
- indexの追加・削除
- SQLを書き換える
- データ型の見直し
DBチューニング
- MySQLパフォーマンスチューニング -my.cnfの見直し
APIサーバ側のチューニング
- 不要なクエリ
- APIサーバとDBのロジックの比率の修正
3. SQLチューニング
やればやるだけ性能が良くなります。チューニングの手順は以下のようになります。
- スロークエリを探す
- explainを使用し実行計画を確認する
- チューニングを行う
具体的なチューニング方法は、以下の3つになります。
[SQLを書き換える]
- サブクエリをできる限りJOIN句に置き換える
- ループ回数を少なくする(N+1問題があれば絶対に修正する)
- 大量データを更新する際は、バルクインサートを行う
[indexの追加・削除]
テーブルの情報を探す時に検索の対象としてよく使用するカラムの値だけを取り出して検索しやすいようにしておいたものです。
indexとは
indexを貼る際のポイント
- カーディナリティの高い(不特定多数のデータが想定される)カラムを選択します。
- 複合インデックスのカラムの順に注意が必要です。順によってインデックスの内容が変わります。
- 更新性能・キャッシュ効率が低下するので、必要なものだけ貼ります。無闇に貼ってはいけません。
[データ型の見直し]
- テーブルに設定したデータ型と入力したデータ型が一致しているか確認が必要です。 型が異なっていた場合、本来は必要のない無駄な型変換処理が行われてしまいます。
- この型変換の処理は、暗黙的に行われてしまうので、発見が少し難しいです。
4. DBチューニング
以下の記事がとても参考になりました。
DBには、MySQLを始めとする様々なものが存在しますが、どのDBでも似たような設定を行うことが可能です。今回は、開発環境で使用しているMySQLを中心に調査しました。
※またPostgreSQLは、こちらの記事が参考になります。
MySQLパフォーマンスチューニング -my.cnfの見直し
チューニングのポイントは以下の通りです。
- スロークエリが発生していないか?
- mysqlのメモリが正しく割り当てられていないか?
- mysqlのログ設定が適切であるか?
- max_connectionの設定が適切であるか?
Mysqlのmy.cofがデフォルトの設定であれば、これらを設定するだけで大幅な改善が可能です。
初期の設定や運用が大変...
- 上記の設定を行うことにより、性能改善は十分に見込まれます。
- しかし、プロダクトの状況に応じ、ベストなパフォーマンスを継続的に維持する方法としては、あまり現実的ではありません...
- もっと楽な良い方法はないのかと.....
と思い調べていたら、AWS Aurora
にたどり着きました。ちょうど、本番環境ではAuroraを使用するようなので少し調べてみました。
5. auroraについて
Amazon Aurora は、MySQL および PostgreSQL と互換性のあるクラウド向けのリレーショナルデータベースであり、従来のエンタープライズデータベースのパフォーマンスと可用性に加え、オープンソースデータベースのシンプルさとコスト効率性も兼ね備えています。
auroraとは
- クラウド向けRDB
- MySQLおよびPostgreSQLと互換性あり
- 標準的なMySQLと比べ、最大5倍の性能差、PostgreSQLと比べ、最大3倍の性能差
- 従来の商用DBと同様なセキュリティ、可用性、信頼性を10分の1のコストで実現
費用面以外で悪く書いてある記事が全く見当たらなかったです....笑
Amazonさんが本気を出したみたいです。記事によっては、「Auroraに合わせて設計を行った方が良い」とまで書かれている記事もありました。
メリット
主なメリットは以下の通りです。
[クエリのスループットの向上]
- CPUを効率的に利用
- 分散ロック機構やQueryChacheの改善による性能向上
[ディスクの可用性の向上]
- オートスケーリング機能
- 容易にバックアップが可能
[複数サーバにシャーディング]
- 複数の小さいDBを1つにまとめる
チューニング方法
[前提]
- デフォルトのパラメータグループを使用することで、十分な高パフォーマンスを実現することができます。
- さらに、高パフォーマンスを実現するためには、主に以下の2つの方法があります。
[方法]
1. 適切なインスタンスタイプを選択
サービスの規模に合わせた適切なインスタンスタイプを選択することで、よりパフォーマンスが最大化されます。
2. 一つのトランザクションで大量の更新や削除を行なったり、大量のデータのシーケンシャルリードを行う場合
auroraのアーキテクチャに合わせてクエリを実行することで性能を向上させることができます。
トランザクションが並列に実行されるワークロード向けにチューニングされているため、クエリを分割することで、並列実行が可能になり性能が向上します。
6. APIサーバ側のチューニングについて
開発を進めていきますと、最初の設計時に想定できなかった大きな仕様変更やバグの発生などが必ず発生します。その際に、パフォーマンスの低下に繋がるようなボトルネックも必ず生まれます。そのため、決まったチューニング方法はありません。SQLやDBチューニングとは異なり、泥臭いものになりやすいです。
チューニングというより、性能改善を目的としたリファクタリングに近いかと思います。
APIサーバとDBのロジックの比率
- 設計段階で議論すべき問題の一つだと思います。
- 全体の設計を考慮しないといけないため、他のチューニングと比較すると、とても難しいです。
[判断材料]
- 仕様
- 開発チームの技術レベル
- プロダクトフェーズ
- 好み ...など
簡単に書き出してみましたが、これらをパフォーマンス面と天秤に掛けて判断するのは、今の自分ではなかなか難しそうです....
不要なクエリを削除
システム上で不要なクエリを発行していないか確認し削除します。
- SQLチューニングと並行して行うことになると思っています。地道で特別な知識は必要ないですが、開発規模が大きくなればなるほど必要になるはずです。
- 特に、ORMを使用している際には、時間をかけて行う価値はあると思います!!実装する際に、想定外のクエリばかり発行されたので......
まとめ
- DBとAPIサーバのパフォーマンスチューニングを行う際のイメージが着きました。
- また、パフォーマンスチューニングには終わりがないため、短時間で効果的なチューニングが大切であることが分かりました。
- 次はフロント側のパフォーマンスチューニングについてもまとめてみたいと思います。