Redis Session 클러스터링

변주환·2024년 3월 5일

Radis

목록 보기
3/3

세션

  • 네트워크 상에서 두 개 이상의 통신장치간에 유지되는 상호 연결
  • 연결된 일정 시간 동안 유지되는 정보를 나타냄
  • 적용 대상에 따라 다른 의미를가짐

Web 로그인 세션

  • Web 상에서 특정 유저가 로그인 했음을 나타내는 정보
  • 브라우저는 Cookie를, 서버는 해당 Cookie 에 연관된 세션 정보를 저장
  • 유저가 로그아웃하거나 세션이 만료될 때 까지 유지되어 유저에 특정한 서비스 가능

분산환경에서의 세션 처리

  • Server 는 세션 정보를 저장 해야함
  • Server가 여러 대라면 최초 로그인한 Server가 아닌 Server는 세션 정보를 알지못함
  • 세션 정보를 Server간에 공유할 방법이 필요

보통 DB에 세션ID,유저정보를 담겠지만 결국 select 해야한다. 목표는 이루어짐 하지만 관계형 데이터베이스를 사용하는게 맞을까?

영속성, 복잡한 데이터가 필요한게 아님 그냥 Key-value 스타일로 일대일 매핑인데?

모든 요청이 DB 에 세션을 찾을텐데 이거 확인한번 해봐야함.

SpringBoot 세션 관리

  • 세션 생성 : 요청이 들어왔을 때 세션이 없다면 만들어서 응답에 set-cokkie로 넘겨줌
  • 세션 이용 : 요청이 들어왔을 때 세션이 있다면 해당 세션의 데이터를 가져옴
  • 세션 삭제 : 타임아웃이나 명시적인 로그아웃 API를 통해 세션을 무효화함

Redis 라이브러리 사용

  • Lettuce : 가장 많이 사용되는 redis 라이브러리. Spring Data Redis 에 내장되어 있음.
  • Spring Data Redis 는 Redis Template 이라는 Redis 조작의 추상 레이어를 제공

Redis 로 값 넣어다 빼보기

@RestController
@RequiredArgsConstructor
public class HelloController {

    private final StringRedisTemplate redisTemplate;

    // setFruit?name=banana
    @GetMapping("/setFruit")
    public String setFruit(@RequestParam String name) {
        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        ops.set("fruit", name);
        return "saved";
    }

    // getFruit
    @GetMapping("/getFruit")
    public String getFruit() {
        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        return ops.get("fruit");
    }
}

세션 클러스터링

서버가 여러대 띄워져있을때 예를 들어 8080 포트 8081 포트 하나 가 있을때
8080포트의 서버에서 로그인 한 후 세션이 저장된 이후 8081 포트로 api 요청을 보내면 다시 로그인을 해야한다. 이유는 세션이 각자 따로 따로 저장되기 때문이다.

이때 이 세션 정보를 redis에 저장해서 두 서버가 redis의 세션정보를 통해서 통신을 하게 된다면 서로 다른 서버라도 동일한 세션을 사용 할 수 있다.

물론 DB 에 세션을 저장해서 중앙에서 관리를 할 수 있지만 매번 요청마다 DB에서 세션유뮤를 select 해오는건 비효율적이다.

@RestController
public class LoginController {

    // /login?name=byeon
    @GetMapping("/login")

    public String login(HttpSession session, @RequestParam String name) {
        session.setAttribute("name", name);

        return "saved.";
    }


    // /myName => "byeon"
    @GetMapping("/myName")
    public String myName(HttpSession session) {
        return (String) session.getAttribute("name");
    }
}

의존성 추가 (세션과 redis 를 이어준다)

implementation 'org.springframework.boot:spring-boot-starter-data-redis'

yml 파일 설정 (직접 해보니 중간 session 설정을 빼도 default 로 동작하는거 같다.)

spring:
  session:
    redis:
      repository-type: default
  data:
    redis:
      port: 6379
      host: localhost

이렇게 설정하면 세션 정보가 redis 로 저장되고 서로 다른 서버 에서도 redis 를 통해서 같은 session 정보를 얻을 수있다.

쿠키를 확인해보며 JSessionID 가 아니라 그냥 SESSION 이 들어간다

0개의 댓글