Redis ‐ 세션 관리 저장 용도 - woojin-playground/Backend-PlayGround GitHub Wiki

📚 Hash 자료 구조 (HSET, HGET, HGETALL)

  • Redis에서 Hash는 하나의 key 안에 여러 개의 field-value 쌍을 저장할 수 있는 자료구조이다.
  • Hash는 json 객체의 구성과 유사해서, 여러 속성들을 묶어서 저장할 때 적합하다.
# Hash에 데이터 저장
# HSET [key] [field] [value]
$ HSET user name jaeseong
$ HSET user age 30
$ HSET user hobby soccer

$ keys * # Hash가 잘 생성됐는 지 확인하기

# Hash에 들어있는 모든 field, value를 조회
# HGETALL [key]
$ HGETALL user

# Hash에 들어있는 특정 field의 value를 조회
# HGET [key] [field]
$ HGET user name
$ HGET user age
$ HGET user hobby

📚 서버가 2대 이상일 경우, Redis로 세션 스토리지를 구축해야 하는 이유

✅ 세션(Session)

  • 서비스에서 로그인 기능을 구현할 때 크게 2가지 방식으로 구현한다. JWT 방식과 세션(Session) 방식이 있다.
  • 그 중에서 세션 방식은 다음과 같은 흐름으로 동작한다.
  1. 사용자가 ID / 비밀번호로 로그인 요청
  2. 서버는 인증이 성공하면 세션 ID를 생성한 뒤, 해당 세션 ID에 사용자 정보를 매핑하여 세션 저장소에 저장
  3. 서버는 응답으로 세션 ID를 쿠키에 담아 클라이언트에게 전달
  4. 이후 클라이언트는 요청마다 쿠키에 포함된 세션 ID를 함께 전송
  5. 서버는 세션 ID를 기준으로 세션 저장소에서 사용자 정보를 조회해서 로그인을 처리

✅ 서버가 2대 이상일 경우, 로컬 세션 스토리지의 문제점

  • 우리가 일반적으로 사용하는 프레임워크(ex. Spring Boot, Nest.js 등)를 살펴보면 각 프레임워크에 내장된 세션 저장소(= 로컬 세션 스토리지)가 존재한다. 그래서 Spring Boot로 예를 들자면, Spring Boot 서버의 일부 메모리 공간에 세션 정보가 저장된다.
  • 이 로컬 스토리지 세션은 서버가 한 대일 경우에는 문제가 안 된다. 하지만 서버가 여러 대 이상일 때는 문제가 발생한다. 왜냐하면 각 서버가 가지고 있는 세션 정보를 서버들끼리 공유하지 않기 때문이다.
  • 그렇게 되면 한 명의 사용자가 로드밸런서에 의해 여러 서버에 요청을 골고루 보내게 될텐데, 어떤 요청에서는 인증이 성공하지만 어떤 요청에서는 인증이 실패하는 상황이 발생한다.
  • 따라서 이를 해결하기 위해 세션 정보를 공유하기 위한 기존 서버와 별개인 외부 세션 스토리지가 필요하다. 외부 세션 스토리지를 사용하게 되면 세션 정보를 외부 세션 스토리지 한 곳에 저장해두면 되기 때문에, 세션 정보를 서로 공유할 수 있게 된다.
  • 기존 스프링 내부의 인메모리 기반으로 세션을 관리하더라도 서버 간 세션을 공유하지 않기 때문에 별도의 외부 저장소인 레디스를 세션으로 사용해 어드민 서버의 세션 관리 방식을 리팩토링한 경험이 있었다.
  • 물론 레디스라는 외부 스토리지를 사용하기 때문에 네트워크 지연은 발생할 수 있으나 서버의 확장이 이루어진다고 하더라도 세션을 공용으로 관리할 곳이 생기기 때문에 서버가 다운된다고 하더라도 안정적으로 서비스를 이어갈 수 있다.