현업에서도 여러가지 용도로 사용되고 있는 Redis
나도 이번 프로젝트 때 로그인 구현 과정에서 사용을 했다.
하지만, 정확하게 알고 사용하는 것이 중요하다고 생각해서 이 글을 정리한다.

과연 Redis란 무엇이며 어떤 용도로 사용이 되고 왜 사용하는 걸까?

NoSQL, Redis

Redis는 Key - Value 쌍으로 Data를 저장하는 전형적인 NoSQL DB이다.
또한 가장 큰 특징인 In-Memory 데이터 구조 를 가진 저장소이다.
그 말인 즉, DB와 같이 저장장치에 저장하지 않아, I/O 없이 캐시처럼 사용할 수 있다.

Redis는 아래와 같은 특징들을 갖는다.

  • Key / Value 구조로 쿼리를 사용할 필요가 없다.
  • In-Memory 구조로 속도가 매우 빠르다.
  • List, Set, Sorted Set, Hashes 등의 자료구조를 지원한다.
  • Single Threaded 구조이다.
    • 한 번에 하나의 명령만 처리할 수 있다.
    • 즉, 연산을 Atomic하게 수행할 수 있다.
    • 처리 시간이 긴 명령어가 들어오면, 앞의 명령어가 모두 처리될 때 까지 대기한다.
  • 읽기 성능 증대를 위한 서버 측 복제(Replication) 지원
  • 쓰기 성능 증대를 위한 클라이언트 측 Sharding 지원
    • Sharding : 수평적 파티셔닝의 한 종류로, NoSQL에서 주로 사용된다.
  • 영속성을 보장한다.
    • RDB(Snapshotting) : 순간적으로 메모리 전체를 Disk에 옮긴다.
    • AOF(Append On File) : Redis의 모든 Write/Update 연산 자체를 모두 Log File에 기록한다.

알아두면 좋은 Cache의 동작!

  • Look Aside(Lazy loading)
    • Cache를 옆에 두고 필요할 때만 Data를 Cache에 적재한다.
    • Key - Value 형태로 저장된다.
    • 실제 사용 Data만 저장되며, Redis의 장애가 App에 영향을 주지 않는다.
      • 하지만, Cache에 없는 Data라면 시간이 더 오래걸린다.
      • Cache가 최신 Data를 가지고 있다고 보장할 수 없다.
  • Write Back
  • Write Through
    • Data를 DB에 작성할 때마다 Cache에 Data를 추가 및 업데이트한다.
    • 이는 항상 Cache를 최신 상태로 유지할 수 있다.
      • 하지만, 쓰지 않는 Data가 Cache에 올라간다.
      • 쓰기 지연 시간이 증가한다.

Redis는 왜 사용할까?

RDB(관계형 데이터베이스)가 버젓이 존재하는데, 왜 굳이 Redis를 사용할까?

DB는 물리 Disk에 직접 데이터를 쓰기 때문에 데이터의 안정성이 보장된다.
하지만 사용자가 늘어났을 때, 부하가 발생할 수 있다는 단점이 있는데,
이럴 때, 캐시 서버 개념으로 Redis를 사용할 수 있다.

Redis의 사용 사례

  1. 좋아요 처리하기
    • 한 사용자가 하나의 댓글에 좋아요를 한 번씩만 할 수 있다.
    • RDBMS에 구현은 가능하지만, 변경이 자주 발생하는 경우 부하가 발생한다.
    • Redis의 Set 을 이용해 간단히 구현이 가능하다.
    • 댓글의 번호를 Key로, 회원 ID를 Value로 추가해주면 간단하다.
  2. 게임의 일일 방문자 수(Unique Visitor) 구하기
    • Google Analytics 같은 외부 서비스를 이용해도 된다.
    • Redis의 비트 연산 을 이용하면 간단하게 구현이 가능하다.
    • 사용자 ID인 비트를 1로 바꾼 뒤, 이후에 BITCOUNT 연산을 통해 구할 수 있다.
  3. 출석 이벤트 구현하기
    • 2번 사례를 응용하면 출석 이벤트 또한 구현이 가능하다.
    • 2번 사례를 통해 매일매일 방문자 수를 계산해서 저장할 수 있다.
    • 그리고, 해당 방문자 수 비트들을 검사하면 매일 출석한 회원 ID 또한 구할 수 있다.
    • 구해놓은 String 간의 비트를 비교하는 BITOP 연산을 이용할 수 있다.

Refresh Token과 Redis

우리는 로그인을 구현할 때, Access Token과 Refresh Token을 모두 사용했다.
Access Token을 서버에서 저장을 할 필요가 없는 반면에,
이후 AT 재발급을 위해 검증 요소로 사용할 Refresh Token은 서버가 저장을 해야 한다.

만약 그냥 RDB에 RT를 저장을 한다면 어떻게 될까?
RT 또한 유효 기간이 존재하기 때문에, 주기적 만료 처리가 번거롭다.
그리고 DB에 대한 접근은 속도가 느린 편이기 때문에, 부하가 발생할 수 있다.

하지만 Redis를 사용한다면 어떨까?
Data에 대한 유효 기간을 설정할 수 있어서, 자동으로 만료시킬 수 있다.
또한 In-Memory 구조의 저장소이기 때문에 접근 시간이 매우 빠르다!