Redis캐싱
- Redis로 캐싱 구현시 mysql과 redis의 데이터 싱크가 맞지않는 문제 발생
- mysql에는 18번까지 존재하지만 redis에는 12번까지만 존재
문제 파악
- 캐시 미들웨어 : req.originalUrl을 key값으로 저장된 데이터가 redis에 존재하면 캐시데이터가 존재하면 redis에 있는 캐시데이터를 리턴하는 미들웨어 작성
- 현재 캐시 미들웨어는 입력된 url의 데이터가 존재하는지만 확인하고 존재하면 바로 데이터를 return하기 때문에 mysql까지 접근하지 않고 전에 저장된 캐시 데이터를 그대로 return 하기때문에 데이터의 싱크가 맞지않는다.
- 데이터의 싱크를 맞추기 위해 여러 고민을 했다
checkCache = async (req, res, next) => {
try {
const cacheData = await redisClient.get(req.originalUrl)
// Redis에 저장된게 존재한다.
if (cacheData) {
console.log("Cashe Hit")
return res.status(200).send({ getPooAll: JSON.parse(cacheData) });
} else {
// Redis에 저장된게 없기 때문에 다음 로직 실행
console.log('Cashe Miss')
next();
}
} catch (error) {
error.failedApi = "캐쉬 미들웨어 에러";
throw error;
}
}
해결방법
- 새로운 푸박스가 등록 됐을때(데이터가 변경됐을때) mysql에 전체데이터를 조회하여 redis에 데이터를 저장하는 코드 추가
- 아래 코드를 추가한 후 푸박스 데이터를 전체 조회 했을때 redis에 저장되어있는 데이터 해쉬를 초기화 하고 새로 등록된 게시물을 포함한 전체데이터가 mysql에서 redis로 복제됨
await redisClient.setEx(originalUrl, DEFAULT_EXPIRATION, JSON.stringify(getPooAll));
추가 사항
- 데이터 캐싱구현을 자주 조회되는 데이터에 대해서만 구현해야함
- redis는 in-memory db이기 떄문에 위치상으로 메모리에 존재함
- 메모리는 처리속도는 빠르지만 용량이적어 많은 데이터를 저장 할 수 없고 휘발성임
- 메인 페이지나 게시글 조회등 자주 조회되는 데이터에 대해서만 캐싱을 적용하고 페이지 안쪽에 있는 자주 조회되지 않는 데이터는 캐싱을 적용하지 않음 => 선택적인 캐싱을 적용하여 캐시 적중률을 높임