はじめまして、サーバサイドエンジニアの立木です。
特定業種向けポータルサイトやスマートフォンゲーム開発などを経て、昨年3月に入社し、現在はANDPADの開発に従事しています。
アンドパッドでは、技術顧問をして頂いてる三谷(mita2)さんによる、データベースに関する勉強会が定期的に行われております。
先日もデータベースの観点から、Webアプリケーションのパフォーマンスをいかにして監視し、改善していくかという勉強会を開催していただきました。
今回はその勉強会について気になったポイントをまとめてみたいと思います。
当日の資料
概要
- ANDPADの現状について分析
- Datadogによる分析手法
- よくある改善パターン
- 質疑応答
ANDPADの現状について分析
当たり前ですが、Webサイトにとってパフォーマンスはとても重要です。
建築業界向けの業務システムであるANDPADであっても、お客様が操作する時にストレスを感じるようでは、業務が回らなくなってしまいます。
少しでも快適に使っていただけるよう、常にパフォーマンスには気を配らなければなりません。
その上で、現在のANDPADはどのような状況なのかを解説していただきました。
概ねの機能は問題なく動作しているようですが、一部の機能でかなりパフォーマンスが低下していることがわかります。
ANDPADではどんどんと新しい機能を追加しておりますが、複雑な業務に対応するアプリケーションとなると、どうしてもパフォーマンスが悪くなることがありそうです。
リリース後も常に監視し、改善を進める必要があります。
Datadogによる分析手法
まずは計測してボトルネックを把握するところから始めることが重要です。その手段として、ANDPADではDatadogを導入しており、その使い方について解説していただきました。
Datadogを使うことで、全体の概要から実際の処理時間まで、かなり多くの情報を確認することが可能です。
「何かわからないけど遅い」という状況で、具体的に遅いのはデータベースに発行されたSQLなのか、プログラムのロジックなのか、他の要因なのか、具体的に確認することが大事ですね。
よくある改善パターン
遅い原因を特定できたところで、どのように改善していけば良いのでしょうか?
今回は主にデータベース寄りの改善方法について、6つまとめられていました。
1. SQLやインデックスを見直す
開発時のテーブル設計で適切なインデックスが存在することが理想ですが、その後の機能修正などにより、元々想定していなかった条件でSELECTが実行されている、というのはよくあることです。
こちらを見直すことで改善が見込まれますが、SQLが複雑だったり、処理するデータが多すぎるなどの原因で対応しきれない可能性もあります。
2. DB上にマテリアライズしておく(キャッシュテーブル)
毎回計算すると負荷が大きすぎるデータに対して、予め別なテーブルに結果を格納しておくことにより、取得時に計算をさせないといった方法です。
データを頻繁に集計して表示するケースでは効果的と思われます。
一方で、集計して格納した値と実際の計算値にズレが発生すると、お客様からの問い合わせにつながったりするため、利用の際には十分に注意が必要です。
3. 非同期でリクエストする
画面全体の描画を先に実行しておき、非同期でサーバサイドにリクエストを発行し、後から取得データを表示する手法です。
最近ではスマートフォンアプリやシングルページアプリケーション(SPA)が増えてきていますので、最初から非同期で設計されるケースも多いのではと思います。
一方で、あくまで体感速度を上げる方法なので、取得情報自体が重たい場合、お客様が欲しいデータを表示するまでには、どうしても時間がかかってしまう可能性があります。
4. キャッシュサーバやメモリにキャッシュ
よく参照されるデータをデータベースよりも早いストレージ(例えばRedis等)に保存しておき、そちらを参照することで、相対的に遅いデータベースへのアクセスを減らし、全体の速度を向上させる手法です。
こちらも比較的よく使われる手法だと思いますが、キャッシュのサイクルを正しく管理しないと、データの不整合やゴミデータによるサーバリソースの圧迫などが問題になることがあります。
また、なんらかの事情でキャッシュサーバがダウンし、全データの再構成が発生した場合に、一斉にデータベースへの問い合わせが発生するため、一時的に高負荷になるといったことも考慮する必要がありそうです。
5. アーキテクチャを見直す
データベースに対して全文検索を実行しているとか、普段は分析が不要なログデータなど、本来RDBで管理すべきでないデータを、他のストレージ等に移動させる手法です。
データベースへの書き込みや問い合わせを大幅に減らせる可能性がありますが、後からこういった仕組みを導入しようとすると、仕様を保ったまま構成を変える必要があるため、かなりの工数がかかる場合もありそうです。
6. 要件を見直す
ANDPADは業務システムなので、複雑な検索条件を指定可能にする要件が多いのですが、利用頻度が少ないわりに負荷が高いとか、そういった機能をなくしたり切り出したりして、要件のレベルでパフォーマンスを改善する手法です。
ただ、パフォーマンスのために要件を犠牲にしてしまうと、結果的にお客様の使い勝手を損なうケースもあり、この手法はプロダクトとしてどうあるべきかの議論とセットになると思います。
質疑応答
残った時間は質疑応答になりましたが、この中で印象に残っているものをいくつか紹介します。
パーティショニングはパフォーマンス改善にどうなのか?
ユーザー単位でパーティショニングすることで、パフォーマンスの改善につながらないか、という質問でした。
- MySQLのパーティションは(Oracle等に比べて)微妙
- ログ的な要素を時間でDROPしたりするケース「だけ」には有用
そもそもIndexが付与されていれば良いのでは、とのことでした。
論理削除ってどう思いますか?
- unique制約に引っかかるならあまり良くないが、それ以外は良いのでは?
- いらないデータを無闇にため込むのは適切ではない
- ログ的に増え続ける場合、適切にクリーニングする運用を考えた方が良い
「論理削除は良くない」といった議論もあったようですが、適切に管理される範囲では問題なさそうです。
実際の業務でも、どうしてもデータを復旧してほしいという依頼もまれにあるため、運用まで含めて設計した方が良さそうですね。
外部キーってどう思いますか?
- 子テーブルの更新で親もロックするので、デッドロックの原因になりやすい
- デッドロックを避けようにも、複数の箇所で更新順を意識するのは難しい
デッドロックの原理については、以前の勉強会で取り上げられていますので、ぜひこちらの記事もご覧ください。
まとめ
「パフォーマンスチューニング」にいろいろな手法があることがわかってはいても、このように言語化されるとわかりやすく、頭が整理されて良かったと思います。
パフォーマンスを監視しつつ、悪化してしまった時になにができるのか、何が適切かを常に考え続けること、それが一番大事であり、お客様の満足につながるのかなと思いました。
ANDPADではエンジニアを募集しています
今回のようなデータベースの勉強会だけでなく、アンドパッドでは様々な勉強会がおこなわれています。
興味を持たれた方は、採用サイトをご覧ください。
スキルアップをしながら一緒にプロダクトを改善していきましょう!