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) 방식이 있다.
- 그 중에서 세션 방식은 다음과 같은 흐름으로 동작한다.
- 사용자가 ID / 비밀번호로 로그인 요청
- 서버는 인증이 성공하면 세션 ID를 생성한 뒤, 해당 세션 ID에 사용자 정보를 매핑하여 세션 저장소에 저장
- 서버는 응답으로 세션 ID를 쿠키에 담아 클라이언트에게 전달
- 이후 클라이언트는 요청마다 쿠키에 포함된 세션 ID를 함께 전송
- 서버는 세션 ID를 기준으로 세션 저장소에서 사용자 정보를 조회해서 로그인을 처리
✅ 서버가 2대 이상일 경우, 로컬 세션 스토리지의 문제점
- 우리가 일반적으로 사용하는 프레임워크(ex. Spring Boot, Nest.js 등)를 살펴보면 각 프레임워크에 내장된 세션 저장소(= 로컬 세션 스토리지)가 존재한다. 그래서 Spring Boot로 예를 들자면, Spring Boot 서버의 일부 메모리 공간에 세션 정보가 저장된다.
- 이 로컬 스토리지 세션은 서버가 한 대일 경우에는 문제가 안 된다. 하지만 서버가 여러 대 이상일 때는 문제가 발생한다. 왜냐하면 각 서버가 가지고 있는 세션 정보를 서버들끼리 공유하지 않기 때문이다.
- 그렇게 되면 한 명의 사용자가 로드밸런서에 의해 여러 서버에 요청을 골고루 보내게 될텐데, 어떤 요청에서는 인증이 성공하지만 어떤 요청에서는 인증이 실패하는 상황이 발생한다.
- 따라서 이를 해결하기 위해 세션 정보를 공유하기 위한 기존 서버와 별개인 외부 세션 스토리지가 필요하다. 외부 세션 스토리지를 사용하게 되면 세션 정보를 외부 세션 스토리지 한 곳에 저장해두면 되기 때문에, 세션 정보를 서로 공유할 수 있게 된다.
- 기존 스프링 내부의 인메모리 기반으로 세션을 관리하더라도 서버 간 세션을 공유하지 않기 때문에 별도의 외부 저장소인 레디스를 세션으로 사용해 어드민 서버의 세션 관리 방식을 리팩토링한 경험이 있었다.
- 물론 레디스라는 외부 스토리지를 사용하기 때문에 네트워크 지연은 발생할 수 있으나 서버의 확장이 이루어진다고 하더라도 세션을 공용으로 관리할 곳이 생기기 때문에 서버가 다운된다고 하더라도 안정적으로 서비스를 이어갈 수 있다.