해당 포스트는 자바스크립트의 기본 문법을 알고있다는 가정하에 작성된 글이며, Node.js 디자인 패턴 책을 참고해 작성된 된 글입니다.
캐시
서버를 운영하다보면 트래픽이 자주 발생되는 동일한 요청이 발견됩니다. 매 동일한 요청마다 연산을 다시 진행하여 클라이언트로 요청을 보내는 일은 상당히 효율적이지 못합니다. 이 부분을 오늘 캐싱을 통해 처리하는 방법을 알려드리고 캐시로 소비되는 메모리를 일정하게 유지하기위한 방법으로 LRU 알고리즘이 적용된 캐시 라이브러리를 사용해보겠습니다.
캐시 구현은 간단한편입니다.
위의 로직대로 작성해보겠습니다.
const totalSales = require('./totalSales')
// 캐시
const cache = {}
/**
*
* 아이템 이름이 캐시 유효기간내에 재요청되었으면 Cache hit!
* 아닐시 요청 처리 후 출력값 캐시에 저장 후 리턴
* @param {String} item 아이템 이름
* @param {Function} cb 콜백 함수
* @returns {Int} 콜백함수 실행 결과 리턴
*/
module.exports = function totalSalesCache(item, cb) {
if(cache[item] !== null && cache[item] !== undefined){
// 캐시에 값이 있다면
return process.nextTick(cb.bind(null, null, item))
}
// 없다면
totalSales(item, (err, res) =>{
// 캐시 유효시간(30초) 설정, 캐시에 값 저장
if(!err){
cache[item] = res
setTimeout(() => {
delete cache[item]
}, 30 * 1000)
}
cb(err, res)
})
}
위 결과가 캐시 사용 전, 아래 결과가 캐시 후 입니다. 눈에 띄게 응답시간이 줄어든 것을 확인하실수있습니다.
LRU(Least Recently Cache) 캐시
위 방식은 인메모리방식으로 비용이 소비되므로 캐시는 관리가 필요합니다. 위의 방식처럼 setTimeout()함수를 사용해 일정 시간이 지나면 사라지도록 만들어도 되지만 해당 값이 30초마다 주기적으로 트래픽이 발생한다면 캐시를 사용하지 못하겠죠?(위 코드의 setTimeout 설정값이 30초)
LRU 캐시는 캐시가 가득차게되면 오랫동안 Cache Hit가 일어나지 않은 데이터를 지움으로써 메모리를 일정하게 유지합니다.
const totalSales = require('./totalSales')
const lru = require('lru-cache')
const opts = {
max : 500,
ttl : 1000 * 60 * 60,
}
const cache = new lru(opts)
module.exports = function totalSalesLRU(item, cb) {
if(cache.has(item)){
const res = cache.get(item)
return process.nextTick(cb.bind(null, null, res))
}
totalSales(item, (err, res) => {
if(!err) cache.set(item, res)
return cb(err, res)
})
}
max : 캐시 사이즈
ttl : 캐시 유효 기간
추가로 더 유용한 옵션들이 있으니 lru-cache 에서 확인 가능하십니다.
'Backend > Node.js' 카테고리의 다른 글
[Node.js 교과서] ch12. NodeAuction 개선하기 1 : 입력값 검증, CSRF 방어 (0) | 2023.04.03 |
---|---|
[Node.js] web token(jwt) 인증 + Redis(In memory) + 최소한의 보안 (0) | 2023.04.01 |
[Node.js 개발자 되기] 7. Token 기반 인증에 대하여 (0) | 2023.02.28 |
[Node.js 개발자 되기] 6. 로그인 구현 (0) | 2023.02.23 |
[Node.js 개발자 되기] 5. HTTP프로토콜 특징 그리고 세션과 쿠키 (0) | 2023.02.23 |