失敗談
過去に業務サーバのリプレース案件に携わったときのことです。
リプレース当日、なんとか作業は完了し動作確認も問題なし。
無事に終わって一安心でしたが、数日後、違和感に気付きました。サーバ内で動作させている業務プログラムの処理が明らかに遅くなっていたのです。
ログを詳しく見ると、データベースへの接続/切断処理で時間がかかっていました。
プログラムのロジックを確認すると、データを1件1件処理するたびにDBセッションの確立と切断を繰り返すという非効率なロジックになっていたのです。
リプレース前まではアプリケーションとデータベースが同じサーバに入っていたのですが、リプレースに伴いサーバを分割したため、データベース接続のオーバヘッドが大きくなり、ロジックの問題が顕在化した、というからくりでした。
データ1件あたりの処理にかかる時間の比較は以下の通りで、16倍も遅くなっています。
リプレース前:0.3秒
リプレース後:4.8秒
解決策としてコネクションプーリングの考え方でプログラムを修正しました。
具体的には、プログラムの開始時にコネクションを確立し、終了時に切断するようにしたことで処理速度が改善しました。
コネクションプーリングとは?
プログラムからデータベースへの接続(コネクション)を確立したあと、データベースへアクセスするたびにそのコネクションを再利用する考え方や技術のことです。コネクションプールともいいます。
今回は「プログラムの開始〜終了まで1回の接続で済ませる」というシンプルな形で対応しましたが、一般的なコネクションプーリングでは複数の接続をまとめて管理し、複数スレッドから効率よく使いまわすといった、より高度な要件にも対応できるようです。
反省と学び
- パフォーマンステストを行うべきだった
本件の最大の問題点は、テスト設計時にパフォーマンスという観点が抜けていたことだと思います。通常の業務と同等のデータ件数でアプリケーションを動かし、性能に問題がないかを確認すべきでした。
どのような案件でも、パフォーマンステストが必要かどうか検討することは忘れないようにしましょう。
また、本件を通してコネクションプーリングの重要性を学びました。
実際、ログを見るとデータベース接続・切断それぞれに1秒ほどかかっており、データベースへの接続はオーバヘッドの大きい処理であるということがよく分かります。(環境によって差はあると思いますが)
データベース接続周りの機能を実装・改修する際はコネクションプーリングの考え方を意識したいですね。
おわりに
当たり前といえば当たり前ですが、パフォーマンステストはシステムの安定稼働を確かめるための大事なテストです。「必要なさそうだから省く」というケースもあると思いますが、「そもそも検討が漏れていた」ということだけは避けましょう。
この記事によって、同じ失敗をする方が少しでも減ると幸いです。