Redis 캐싱
프로젝트 작업 시 재고 조회를 Redis 캐싱 처리를 해서 관리하고자 한다.
선착순 구매 작업시 많은 사용자들이 재고를 조회하고 그 재고를 바탕으로 주문을 해야 하게 때문에 db에서 재고를 조회하는 대신에 인메모리 db로 동작하는 redis를 선택해 빠르게 데이터를 조회할 수 있도록 하려 한다.
캐싱 방법으로는
로컬 메모리 캐싱, 데이터베이스 캐싱등 여러 방법이 있지만
다양한 데이터 구조를 지원하고 확장성이 뛰어난 Redis를 사용해 캐싱하려 한다!
캐싱 전략
캐싱 전략은 웹서비스의 시스템 향상을 기대할수 있는 중요한 기술 중 하나이다.
일반적으로 캐시는 메모리를 사용하기 때문에 데이터베이스 보다 훨씬 빠르게 데이터를 응답할 수 있다.
메모리는 용량이 크지 않고, 데이터베이스보다 비싸기 때문에 적절한 곳에 사용되어야 한다.
캐시 전략을 잘 짜서 사용할 필요가 있다.
읽기 전략(Cache-Aside)
- 반복적 읽기가 많은 호출에 적합
- 캐시와 DB가 분리되어 가용되기 때문에 원하는 데이터만 별도로 구성하여 캐시에 저장
Cache-Aside 패턴은 효율적인 메모리 사용과 / 데이터 일관성 관리가 용이하다.
특히 재고의 경우 자주 조회 되는 데이터가 캐시에 유지되어 메모리 낭비가 적기때문에 해당 패턴이 적당하다고 판단했다.
- 캐시에 데이터가 있는지 확인
- 데이터가 없으면 DB에서 데이터 찾기 / 가져온 데이터 캐시에 저장
- 데이터응 사용자 한데 전달
쓰기 전략(Write Behind)
- 캐시와 DB동기화를 비동기 하기 때문에 동기화 과정이 생략
- 데이터를 저장할 때 DB에 바로 쿼리 하지 않고, 캐시에 모아 일정 주기 배치 작업을 통해 DB에 반영
- 캐시에 모아놨다가 DB에 쓰기 때문에 쓰기 쿼리 회수 비용과 부하를 줄일 수 있음
쓰기 전략을 정확히 Write Behind 라고 표현하기는 어렵지만 이 패턴에 가까운 거 같다
주문 생성시 캐시에 있는 재고에만 수량 감소를 주었고, 결제가 완전히 이루어졌을 때만 데이터베이스에 접근해 수량을 감소하게 하였다.
주문을 하고 결제를 하지 않았는데 재고를 바로 감소한다면 최종적으로 결제의 여부에 따라 쿼리가 또 발생할수 있었다. 불필요한 쿼리를 줄이고자 해당 쓰기 전략을 선택했다.
하지만 이 과정에서 고려해봐야할 점이 있다.
캐시를 사용하게 되면 꼭 고민해봐야할 문제, "데이터 정합성" 문제이다.
나 또한 주문만 하고 결제가 이루어지지 않았을 경우에 cache에 수량과 데이터베이스의 수량이 일치하지 않는 구간이 발생하였다.
하지만 내가짠 로직의 경우 데이터베이스에 바로 반영하는 캐시 전략을 사용했을 때 크게 성능 개선이 되지 않았다.
그래서 주문이 들어왔을때 캐시에 있는 수량만 감소시키는 방향으로 로직을 작성했다.
주문 이후 15분 이상 결제 하지 않을 경우 캐시를 돌려주고, 최종적으로 결제를 한경우에만 데이터베이스의 수량을 감소시킴으로써 궁극적 일관성을 유지할 수 있었다!
💡궁극적 일관성( Eventual Consistency )
시스쳄이 일시적으로 일관성이 깨질 수 있지만, 결국에는 모든 복제된 노드 간에 데이터가 일치하게 되는 것
가용성을 극대화하기 위해, 모든 순간 노드 간의 즉각적인 동기화를 피하고, 일관성을 점진적으로 유지시킬 수 있었다.
성능과 일관성간의 트레이드오프를 잘 고려해야 하는 문제인 거 같다.
💡트레이드 오프 (Trade-off)
트레이드 오프는 한 가지 목표를 달성하기 위해 다른 목표를 희생하는 상황을 나타냅니다. 대규모 트래픽 처리에서는 일관성, 가용성, 분할 내성 등의 목표가 동시에 충족되기 어렵기 때문에 트레이드 오프를 고려하는 것이 중요합니다.
결과
1000건의 요청을 보냈을때 성능이 개선된걸 확인할수 있었다!
TPS( Throughput: 초당 처리한 요청 수 )
62.5/sec -> 94.9/sec (약 51.84%성능 개선)
'프로젝트 > Springboot-MSA- PreOrder' 카테고리의 다른 글
[Project] 프로젝트 회고 (0) | 2024.09.18 |
---|---|
[Project] Kafka를 사용한 비동기 이벤트 처리 (0) | 2024.09.06 |
[Project] 데이터 동시성 문제 해결 (4) | 2024.08.26 |
[Project] 서비스 장애 대응 Circuit Breaker 구현 (1) | 2024.08.26 |
[Project] API Gateway (0) | 2024.08.18 |