반응형
Node-Cache는 Node.js 애플리케이션에서 메모리 캐싱을 구현할 수 있게 해주는 간단하고 강력한 모듈입니다. 데이터베이스 쿼리 결과나 API 응답을 캐싱하여 애플리케이션의 성능을 향상시킬 수 있습니다.
기본 설치 및 설정
const NodeCache = require('node-cache');
// 기본 캐시 인스턴스 생성
const cache = new NodeCache({
stdTTL: 600, // 기본 TTL 10분
checkperiod: 120 // 만료된 항목 점검 주기 2분
});
기본적인 캐시 사용법
// 데이터 저장
cache.set('user:123', { name: 'John', age: 30 });
// 데이터 조회
const data = cache.get('user:123');
// 여러 키 한번에 조회
const multiData = cache.mget(['user:123', 'user:124']);
// 데이터 삭제
cache.del('user:123');
FastAPI와 함께 사용하기
const express = require('express');
const NodeCache = require('node-cache');
const app = express();
const cache = new NodeCache();
app.get('/users/:id', async (req, res) => {
const { id } = req.params;
const cacheKey = `user:${id}`;
// 캐시 확인
const cachedData = cache.get(cacheKey);
if (cachedData) {
return res.json(cachedData);
}
// DB 조회
try {
const user = await database.getUser(id);
// 캐시에 저장
cache.set(cacheKey, user, 3600); // 1시간 캐시
res.json(user);
} catch (error) {
res.status(500).json({ error: 'Server error' });
}
});
고급 캐시 패턴
// 캐시 미들웨어
const cacheMiddleware = (duration) => {
return (req, res, next) => {
const key = `__cache__${req.originalUrl}`;
const cachedResponse = cache.get(key);
if (cachedResponse) {
res.json(cachedResponse);
return;
}
res.originalJson = res.json;
res.json = (body) => {
cache.set(key, body, duration);
res.originalJson(body);
};
next();
};
};
// 사용 예시
app.get('/popular-posts', cacheMiddleware(300), async (req, res) => {
const posts = await getPosts();
res.json(posts);
});
캐시 이벤트 처리
// 캐시 만료 이벤트
cache.on('expired', (key, value) => {
console.log(`Cache key ${key} has expired`);
// 필요한 정리 작업 수행
});
// 캐시 삭제 이벤트
cache.on('del', (key, value) => {
console.log(`Cache key ${key} was deleted`);
});
// 캐시 설정 이벤트
cache.on('set', (key, value) => {
console.log(`New cache entry: ${key}`);
});
패턴별 캐시 구현
데이터베이스 쿼리 캐싱
class CachedDatabase {
constructor() {
this.cache = new NodeCache({ stdTTL: 3600 });
}
async getUser(id) {
const cacheKey = `user:${id}`;
let user = this.cache.get(cacheKey);
if (!user) {
user = await database.findUser(id);
this.cache.set(cacheKey, user);
}
return user;
}
invalidateUser(id) {
this.cache.del(`user:${id}`);
}
}
API 응답 캐싱
class ApiCache {
constructor() {
this.cache = new NodeCache({
stdTTL: 600,
checkperiod: 60
});
}
async fetchWithCache(url, options = {}) {
const cacheKey = this.generateKey(url, options);
let data = this.cache.get(cacheKey);
if (!data) {
const response = await fetch(url, options);
data = await response.json();
this.cache.set(cacheKey, data);
}
return data;
}
generateKey(url, options) {
return `${options.method || 'GET'}:${url}`;
}
}
성능 모니터링
class CacheMonitor {
constructor(cache) {
this.cache = cache;
this.stats = {
hits: 0,
misses: 0
};
this.setupMonitoring();
}
setupMonitoring() {
// 캐시 히트 모니터링
const originalGet = this.cache.get;
this.cache.get = (...args) => {
const value = originalGet.apply(this.cache, args);
value ? this.stats.hits++ : this.stats.misses++;
return value;
};
}
getStats() {
const hitRate = this.stats.hits / (this.stats.hits + this.stats.misses);
return {
...this.stats,
hitRate: hitRate || 0
};
}
}
주의사항
- 메모리 사용량
- 적절한 TTL 설정
- 주기적인 캐시 정리
- 캐시 무효화
- 데이터 업데이트 시 관련 캐시 삭제
- 일관성 유지
- 동시성 처리
- Race condition 방지
- 락 메커니즘 고려
- 모니터링
- 캐시 히트율 추적
- 메모리 사용량 감시
Node-Cache는 간단하면서도 강력한 캐싱 솔루션을 제공합니다. 적절히 활용하면 애플리케이션의 성능을 크게 향상시킬 수 있습니다.
'TypeScript' 카테고리의 다른 글
Zod: TypeScript 스키마 검증 (0) | 2025.02.20 |
---|---|
React Hook Form: 폼 상태 관리 (0) | 2025.02.19 |
React : map (0) | 2025.02.16 |
React useEffect 의존성 경고 (1) | 2025.02.14 |
Nginx 413 Request Entity Too Large 오류 해결 (0) | 2025.02.13 |