今回はSpring Boot開発の現場で役立つTipsとして、シングルトンパターンとキャッシュを組み合わせたTBLデータのキャッシュ実装についてご紹介します。長い期間不変なマスタテーブルの値とかを保持できるので、毎回クエリを発行せずに済む、というメリットがあります。
シングルトンとキャッシュで実現する高速化
アプリケーションにおけるパフォーマンスの重要性
Webアプリケーションにおいて、パフォーマンスはユーザーエクスペリエンスを大きく左右する重要な要素であり、表示速度が遅いと、ユーザーの離脱率増加やコンバージョン率低下につながる可能性があります。特に、近年ではモバイル端末からのアクセス増加や、ユーザーの応答速度に対する期待値向上など、パフォーマンスの重要性はますます高まっています。特にWebだと「ターンアラウンドタイム(TAT)3秒以内」なんて目標設定されたりするので、ボトルネックは少ないほうがいいです。
TBLデータのキャッシュとは?
TBLデータのキャッシュとは、データベースから取得したデータをアプリケーションサーバーのメモリ上に保持し、次回以降のアクセス時に高速に参照できるようにする仕組みです。データベースへのアクセスは、ネットワークのオーバーヘッドやディスクI/Oが発生するため、比較的時間のかかる処理です。キャッシュを利用することで、これらの処理を削減し、アプリケーション全体の応答速度を向上させることができます。
シングルトンパターンとキャッシュの組み合わせ
シングルトンパターンは、クラスのインスタンスが1つだけ生成されることを保証するデザインパターンです。キャッシュをシングルトンとして実装することで、アプリケーション全体でキャッシュデータを共有し、効率的に利用することができます。また、キャッシュの初期化処理を1回だけ行うことで、オーバーヘッドを削減することも可能です。
Spring Bootでシングルトンなキャッシュを実装する方法
Spring Bootにおけるシングルトンパターンの実装
Spring Bootでは、@Component
などのアノテーションを用いることで、簡単にシングルトンなBeanを定義することができます。キャッシュクラスに@Component
アノテーションを付与することで、Springコンテナによって管理され、シングルトンなインスタンスが生成されます。
シングルトンなキャッシュクラスの実装
シングルトンなキャッシュクラスのサンプルコードです。
既にキャッシュされていれば、キャッシュ値を返却、そうでなければTBL検索結果を返却、みたいな感じです。簡素ですが、これだけでキャッシュが実現できます。
@Component
public class SampleService {
@Autowired
private SampleMapper sampleMapper;
// メンバ変数に保持したいオブジェクトを定義
private SampleEntity cacheEntity;
// これがメイン処理
public SampleEntity execute() {
if(cacheEntity != null) {
// 既にキャッシュされていれば、キャッシュ値を返却
return cacheEntity;
}
// キャシュされていないときは、クエリ発行し結果を保持
cacheEntity = sampleMapper.select();
return cacheEntity;
}
}
利用する際の注意点
キャッシュデータの整合性
キャッシュを利用する場合、キャッシュデータとデータベースデータの整合性を保つことが重要です。キャッシュの更新処理に失敗した場合など、データの不整合が発生する可能性があります。常に最新のトランザクションデータを参照したい場合は利用しない方が良いです。
メモリ使用量
キャッシュは、メモリ上にデータを保持するため、メモリ使用量に注意する必要があります。キャッシュサイズが大きすぎると、OutOfMemoryが発生する可能性があります。
どのようなデータに適しているの?
以下のようなデータはキャッシュする対象として検討していいと思います。
- 参照頻度が高く、更新頻度が低いもの(マスタデータ、起動パラメータとか)
- 更新頻度が高いが、即時性が求められないもの(リコメンドとか)
まとめ|適度なキャッシュは必要
今回は、Spring Bootでシングルトンパターンとキャッシュを組み合わせたTBLデータのキャッシュ実装について紹介しました。キャッシュを適切に利用することで、アプリケーションのパフォーマンス向上が可能です。ただし、キャッシュ利用には注意点もあるため「どういうデータをキャッシュ対象とするか」をルールとして定めておいた方が吉です。