Skip to content

なぜキャッシングが重要なのか

⚡ なぜキャッシングが重要なのか

Section titled “⚡ なぜキャッシングが重要なのか”

キャッシングは、アプリケーションのパフォーマンスを向上させる重要な技術です。適切なキャッシングにより、レスポンスタイムを短縮し、サーバーリソースを効率的に使用できます。

❌ キャッシングなしのアプリケーションの問題

Section titled “❌ キャッシングなしのアプリケーションの問題”

❌ 問題のある実装:

// キャッシングなし: 毎回データベースにアクセス
async function getUser(userId: string) {
// 毎回データベースクエリが実行される
const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]);
return user;
}
// 問題点:
// - データベースへの負荷が高い
// - レスポンスタイムが遅い
// - スケーラビリティが低い

⚠️ 影響:

  • 📈 データベースの負荷増加
  • ⏱️ レスポンスタイムの増加
  • 📉 スケーラビリティの低下
  • 💸 コストの増加

✅ 改善された実装:

// キャッシングあり: キャッシュから取得
async function getUser(userId: string) {
// キャッシュから取得を試みる
const cached = await cache.get(`user:${userId}`);
if (cached) {
return cached;
}
// キャッシュにない場合はデータベースから取得
const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]);
// キャッシュに保存
await cache.set(`user:${userId}`, user, 3600); // 1時間
return user;
}
// メリット:
// - データベースへの負荷が軽減される
// - レスポンスタイムが短縮される
// - スケーラビリティが向上する

1. アプリケーションレベルキャッシング

Section titled “1. アプリケーションレベルキャッシング”

定義: アプリケーション内でデータをキャッシュします。

使用例:

// メモリキャッシュ
const cache = new Map<string, any>();
function getUser(userId: string) {
if (cache.has(userId)) {
return cache.get(userId);
}
const user = fetchUser(userId);
cache.set(userId, user);
return user;
}

2. データベースレベルキャッシング

Section titled “2. データベースレベルキャッシング”

定義: データベースのクエリ結果をキャッシュします。

使用例:

-- クエリキャッシュ(MySQL)
SET GLOBAL query_cache_size = 1000000;
SET GLOBAL query_cache_type = ON;

定義: 静的コンテンツをCDNでキャッシュします。

使用例:

// CloudFrontなどのCDNで静的コンテンツをキャッシュ
// 画像、CSS、JavaScriptファイルなど

定義: アプリケーションがキャッシュを管理します。

フロー:

1. キャッシュからデータを取得を試みる
2. キャッシュにない場合はデータベースから取得
3. データをキャッシュに保存

実装例:

async function getUser(userId: string) {
// キャッシュから取得
let user = await cache.get(`user:${userId}`);
if (!user) {
// データベースから取得
user = await db.query('SELECT * FROM users WHERE id = ?', [userId]);
// キャッシュに保存
await cache.set(`user:${userId}`, user, 3600);
}
return user;
}

定義: データの書き込み時に、キャッシュとデータベースの両方に書き込みます。

フロー:

1. データベースに書き込み
2. キャッシュにも書き込み

実装例:

async function updateUser(userId: string, data: UserData) {
// データベースに書き込み
const user = await db.query(
'UPDATE users SET ? WHERE id = ?',
[data, userId]
);
// キャッシュにも書き込み
await cache.set(`user:${userId}`, user, 3600);
return user;
}

定義: データの書き込みをキャッシュにのみ行い、後でデータベースに書き込みます。

フロー:

1. キャッシュに書き込み
2. 非同期でデータベースに書き込み

実装例:

async function updateUser(userId: string, data: UserData) {
// キャッシュに書き込み
await cache.set(`user:${userId}`, data, 3600);
// 非同期でデータベースに書き込み
setImmediate(async () => {
await db.query('UPDATE users SET ? WHERE id = ?', [data, userId]);
});
return data;
}
// TTLを設定して自動的に無効化
await cache.set(`user:${userId}`, user, 3600); // 1時間
// データ更新時にキャッシュを無効化
async function updateUser(userId: string, data: UserData) {
await db.query('UPDATE users SET ? WHERE id = ?', [data, userId]);
// キャッシュを無効化
await cache.delete(`user:${userId}`);
}

キャッシングが重要な理由:

  • パフォーマンス: レスポンスタイムを短縮できる
  • スケーラビリティ: サーバーリソースを効率的に使用できる
  • コスト: データベースへの負荷を軽減できる
  • ユーザー体験: ユーザー体験を向上させられる

適切なキャッシングにより、アプリケーションのパフォーマンスを大幅に改善できます。