[AvAb] Redis 도입하기

엄기훈·2024년 1월 19일
0

AvAb

목록 보기
2/4
post-thumbnail

🧱 Redis 필요성 & 요구사항

서비스를 구현하면서 Redis의 필요성을 느끼게 되었습니다.
마침 Redis를 써보고 싶었던 참에 프로젝트를 진행하면서 배울 수 있는 좋은 기회가 될 듯 하여 팀원들과 논의해 사용해보기로 했습니다.

Refresh Token

현재 프로젝트는 JWT를 이용해 인증&인가를 수행하고 있습니다.
또, 자동 로그인 기능을 구현하기 위해서 Refresh Token까지 사용할 예정입니다.

Refresh Token 특징
1. 토큰 일치 여부 확인을 위해 서버에 저장되어야 한다.
2. 주기적으로 효력을 잃는다.

Refresh Token을 DB에 저장하게 되면 만약 DB가 유출될 시 (일어나서도 안되지만) 큰 보안 사고로 이루어질 수도 있습니다.
DB와 별도의 저장소에 Refresh Token을 저장해야 만약 DB가 유출되더라도 Refresh Token은 안전하게 지킬 수 있습니다.
(일종의 한 바구니에 계란을 한 번에 넣지 않는 이유랄까...?)

또한 Refresh Token은 주기적으로 토큰의 효력을 잃게 됩니다.
Access Token이 당장의 서비스 사용을 위해 매우 짧은 유효 기간(30분 ~ 1시간)을 갖고 있다면, Refresh Token은 자동 로그인을 위해 1주에서 2주 정도의 유효 기간을 갖게 됩니다.
Redis의 경우 메모리 기반이라 유효 기간을 설정해두면 해당 값이 소멸되는 특징이 있어 Refresh Token을 저장하기에 알맞다고 판단했습니다.

조회수

인기 레크레이션 목록을 위해 레크레이션의 조회수를 저장할 필요성을 느끼게 되었습니다.
DB에서 가장 부하가 큰 것이 조회인 만큼 조회수 관리를 위해서는 성능 최적화는 필수입니다.
단순하게 레크레이션을 조회했을 때 DB의 조회수 칼럼이 증가하게 구현하면 반드시 성능이 떨어지게 될 것이라고 생각했고 이를 최적화할 방법을 모색하게 되었습니다.

여러 방법을 찾던 중 Write-Back 전략을 사용하면 최적화가 가능할 것 같다는 결론에 도달았습니다.

Write-Back: 데이터의 변화가 필요할 때마다 변화를 주는 것이 아닌 해당 변화를 계속 누적했다가 일정 기간마다 그 변화를 한 번에 반영하는 전략

조회수도 레크레이션이 조회될 때마다 DB의 컬럼을 변화시키는 것이 아닌, Redis로 해당 조회수의 변화를 계속해서 누적했다가 일정 기간마다 DB의 조회수로 반영하여 부하를 감소시킬 수 있습니다.

💻 로컬 컴퓨터에 Redis 설치

저는 macOS 환경이라 macOS 환경을 바탕으로 소개하겠습니다!
설치 방법을 찾아보니 Docker로 하시는 분들이 많은 것 같았습니다.
굳이 그래야 하나...? MySQL처럼 깔 수 있지 않을까? 해서 공식 문서를 찾아보니 맥에서는 homebrew로 쉽게 설치할 수 있었습니다! (hombrew 만세!)

명령어 하나만으로 redis를 설치할 수 있습니다.

brew install redis

설치가 완료되었다면 foreground로 실행하거나

redis-server

아니면 background로 실행할 수 있습니다.

brew services start redis

Redis가 실행 중이라면 redis-cli로 redis에 접근할 수 있습니다.

☁️ ElastiCache 설정

AWS로 ElastiCache 인스턴스를 만드는 방법은 추후 CI/CD 시리즈로 다루어볼까 합니다!
추후 게시물을 기대해주세요.

🍃 Spring Boot와 연동하기

Spring Boot의 Redis 접근 방식

스프링 부트에서 Redis에 접근을 위해 크게 두 가지 방식을 제공합니다.
1. Redis Template

  • Redis 연결을 위한 설정 클래스들을 작성하여 유연한 접근이 가능합니다.
  • 사용자가 직접 레디스에 명령을 전달해 쿼리를 수행합니다.
  • 레디스의 다양한 기능을 사용할 수 있습니다.

2. Redis Repository

  • JPA에서 제공하는 Repository 패턴과 유사하게 사용할 수 있습니다.
  • 레디스 접근에 높은 추상화를 제공해 데이터에만 집중할 수 있습니다.

두 가지 방식을 고려하였을 때, 설정 클래스 작성이 불필요하고 빠르게 접근이 가능한 Redis Repository 방식을 선택하여 사용하기로 했습니다.

접근 설정

현재 프로젝트에서는 로컬 환경과 개발 환경을 나누어 서버를 구동하고 있습니다.
로컬 환경은 단순 개인 컴퓨터로 개발 할 때 사용하고, 개발 환경은 프런트가 개발할 때 사용할 수 있게 구성한 서버입니다.
따라서 Redis도 로컬 환경에서는 로컬 Redis를 사용하게 하고, 개발 서버에서는 ElastiCache의 Redis를 이용하도록 구성해야 했습니다.
이러한 점을 반영해 application.yml을 수정했습니다.

## Default profile
spring:
  application:
    name: avab-dev
  profiles:
    active: dev
# 중략
---
# Local Profile
spring:
  config:
    activate:
      on-profile: local
  # 중략
  data:
    redis:
      host: localhost
      port: 6379
# 중략
---
# Dev Profile
spring:
  config:
    activate:
      on-profile: dev
# 중략
  data:
    redis:
      host: ${REDIS_URL}
      port: 6379
# 중략
---

개발 환경에서는 REDIS_URL을 환경 변수로 주입 받아 사용하게 됩니다.
이 때, REDIS_URL이 ElastiCache 인스턴스의 주소가 됩니다.
주의해야 할 점은 해당 주소 맨 끝에 :6379 부분은 제외하고 환경 변수로 설정해주어야 합니다.

⏩️ 이어서

다음 포스트에서는 스프링 스케쥴러와 Write-Back을 활용한 조회수 최적화 방식에 대해 다루어 보겠습니다!

profile
한 번 더 고민해보는 개발자

0개의 댓글