취준생 프로젝트

🛠️ [1편 Spring] Redis Caching 사용하여 스크랩 성능 개선

한둥둥 2024. 12. 18. 18:22

우선 저는 Redis Caching 전략을 고려한 결과..! 

Look Aside + Write Back패턴을 사용하였습니다. 

 

코드에 관해서 설명해드리기 전에, 왜 이런 전략 패턴을 사용하게 되었는지, Redis에 대표적인 전략 패턴을 알아보도록 하겠습니다. 

 

Look Aside 패턴 

 

- Cache Aside 패턴 

- 데이터를 찾을 때, 캐시에 저장되어 있는지 우선적으로 확인하는 전략 , 캐시에 데이터 없으면 DB에서 조회

- 반복적인 읽기가 많은 작업에 적합 

- 캐시 DB가 분리되어 가용 되기 때문에 원하는 데이터만 별도로 캐시에 저장해줌 

- 캐시와 DB 분리되어 가용되어 캐시 장애가 대비 되어있는 형태이다. 만일 redis가 다운되어도 DB에서 데이터를 읽어 올 수 있음. 

 

 

해당 그림을 구조로 되어있음 

1. Cache Store 검색하는 데이터가 있는지 확인함. (cache hit)

2. Cache Store 데이터가 없을 경우 DB조회 (cache miss)

3. DB에서 조회해온 데이터를 Cache Store 업데이트 

 

해당 구조는 일반적으로 사용되는 기본적인 캐시 전략이다. 

 

[Cache Warming] 

미리 캐시로 db의 데이터를 밀어 넣어두는 작업을 의미한다. 

이 작업을 수행하지 않으면 서비스 초기에는 초기에 트래픽 급증 시 대량의 cache miss 가 발생하여 데이터베이스에 부하가 급증 할 수 있음. 

 

Read Throug 패턴 

- 캐시에서만 데이터 읽어오는 전략 (inline cache)

- Look Aside 비슷 but 데이터 동기화 라이브러리 또는 캐시 제공자에게 위임하는 방식

- 데이터 조회 전체적으로 속도가 ⬇️

- 데이터 조회는 전적으로 캐시에만 의지, redis 다운 시 서비스 이용 차질 

- 캐시와 DB간의 데이터 동기화가 항상 이루어짐

- 읽기가 많은 워크로드에 적합

 

1. Cache Store 에 검색하는 데이터가 있는지 확인 (Cache hit)

2. Cache Store 없는 경우 데이터베이스 조회하여 업데이트

3. 캐시에서 조회 

 

캐시 쓰기 전략 (Write Cache Strategy)

Write Back 패턴

- Write Behind 패턴이라고 불린다.

- 캐시와 DB 동기화를 비동기하기 때문에 동기화 과정이 생략

- 데이터를 저장할 때 DB에 바로 쿼리하지 않고, 캐시에 모아서 일정 주기 배치 작업을 통해 DB 반영

- 데이터를 저장할 때 DB에 바로 쿼리하지 않고, 캐시에 모아서 일정 주기 배치 작업을 통해 DB 반영

- 캐시에 모았다가 DB에 쓰기 때문에 쓰기 쿼리 회수 비용과 부하를 줄일 수 있다. 

- 자주 사용되지 않는 불필요한 리소스 저장됨

- 캐시에서 오류 발생 데이터 영구적으로 소실

 

 

해당 전략은 Replication or Cluster 구조 적용함으로써 Cache 가용성을 높이는 것이 더 좋다고 한다. 

하지만 나는.. 하지 않았다. 추후에 해볼 예정이다. 

 

Write Through 패턴 

- 데이터베이스와 Cache에 동시에 데이터를 저장하는 전략 

- 데이터를 저장할 때 먼저 캐시 저장 -> 바로 DB 저장

- Read Through 동일하게 DB 동기화 작업 캐시에 위임 

- DB , 캐시 항상 동기화 되어 있음

- 데이터 유실 안되는 상황에 적합 

 

1. DB에 저장할 데이터가 있으면 우선 Cache Store에 저장 

2. Cache Store에서 바로 DB 저장 

 

TTL 꼭사용하여 사용하지 않는 것은 반드시 삭제해야함. 

 

 

Write Around

- Write Throug 보다 빠름

- 모든 데이터 DB wjwkd

- Cache miss 발생하는 경우에만 DB와 캐시에도 데이터를 저장 

- 따라서 캐시와 DB 내의 데이터가 다를 수 있음. 

 

 

저는 Look Aside + Write Back패턴 사용하였습니다. 

왜냐면 Look Aside를 통해서 스크랩 같은 경우는 자주 사용되며 반복적인 읽기가 강한 작업이라 생각했습니다. 왜냐면 해당 데이터가 스크랩한 유저인지 판단해야하고 구독중인 경우, 바로 취소하는 경우도 많습니다. 이러한 결과에 따라서 Look Aside 정책을 결정하였습니다. 

또한 장애가 발생하여도 디비에서 조회 가능하기에 지속적인 서비스를 유지 할 수 있다는 장점도 맘에 들었습니다. 

 

Write Back 패턴을 채용하게 된 이유는 스크랩의 경우 많은 유저가 손쉽게 스크랩을 사용하는 기능이고, 바로바로 DB에 저장하는 방식은 비효율적이라고 생각하였습니다. 그래서 한번에 모았다가 스케줄러를 통하여 비동기 방식으로 저장하면 더 효율적으로 작동할 것이라는 판단을 하였습니다. 

또한 스크랩 데이터의 경우 데이터를 영구 손실해도 시스템에 영향을 끼치는 범위와 어느정도 타협 할 수 있다는 판단을 하여 Write Back 패턴으로 진행하게 되었습니다. 

 

다음에는 스프링 코드를 어떻게 작성했는지에 대해 포스팅하고 Jmeter를 통한 성능 분석 결과를 공유하겠습니다.