Redis내부에 session 저장/삭제

sieun·2022년 2월 2일
1
post-thumbnail

개요

e-commerce 대용량 서버 프로젝트에서 session storage로 redis를 적용하였습니다. redis session을 적용한 이후로는 redis로 들어가 조회할 일이 거의 없기 때문에 session이 어떻게 저장되고 삭제되는지 확인해보려고 합니다.

code

해당 프로젝트는 다음 github에서 확인 가능합니다.
https://github.com/f-lab-edu/online-marketplace

SessionLoginService.class

@Override
    public void login(SignInRequestDto dto){
    
        ...
        
        // 이메일이 존재하고 패스워드가 일치하면 세션에 데이터 저장
        httpSession.setAttribute(SessionKey.LOGIN_USER_ID, user.get().getId());
    }

    @Override
    public void logout(){
    	// 세션에 해당 세션키에 대한 데이터 삭제
        httpSession.removeAttribute(SessionKey.LOGIN_USER_ID);
    }

SessionKey.class

public class SessionKey {

    public static final String LOGIN_USER_ID = "USER_ID";
}

RedisConfig.class

@EnableRedisHttpSession
@Configuration
public class RedisConfig {

	@Value("${spring.redis.session.host}")
	private String redisHost;

	@Value("${spring.redis.session.port}")
	private int redisPort;

	@Bean
	public RedisConnectionFactory redisConnectionFactory() {
		return new LettuceConnectionFactory(new RedisStandaloneConfiguration(redisHost, redisPort));
	}
}

redis에서 데이터 조회

Postman으로 localhost:8080/users/login에 POST요청을 한 후, redis-cli로 확인하면 다음과 같이 데이터가 저장된 것을 확인할 수 있습니다.

세션을 저장하면 3가지의 데이터를 조회할 수 있습니다.

  • spring:session:sessions:(session id)
    세션 정보가 저장됨. hash타입
  • spring:session:sessions:expires:(session id)
    세션 만료 키. string타입
  • spring:session:expirations:(expire time)
    만료시간에 삭제될 세션 정보. set타입

spring:session:sessions:expires의 세팅 과정과 세션 만료시간을 키로 지정하는 이유를 공식문서에서 찾을 수 있었습니다.

세션 키 자체로 만료시간을 추적하여 데이터를 조회할 수 없어서 만료시간 키가 사용됩니다.

세션 정보가 spring:session:sessions에 저장되어 있는지 확인해보았습니다.

spring:session:sessions에는 다음과 같이 저장되어 있었습니다.

  • creationTime 세션 생성시간
  • lastAccessedTime 마지막 세션 조회 시간
  • sessionAttr 세션에 저장한 데이터
  • maxInactiveInterval 만료시간

sessionAttr에서는 저희가 setAttribute()메소드를 사용하여 저장한 세션키 USER_ID가 들어있습니다.

저장된 데이터 USER_ID의 값을 조회해보겠습니다.

사용자의 id가 알아보기 힘든 형태로 출력되었습니다. 공식 문서에는 다음과 같이 알려줍니다.

즉, RedisTemplate으로 객체와 Redis의 기본 이진 데이터간의 데이터 직렬화/역직렬화를 하는데 사용되는 방식이 Jdk 직렬화 방식(JdkSerializationRedisSerializer)이기 때문이라고 합니다.


redis에서 데이터 삭제

localhost:8080/users/logout에 GET요청을 하면 해당 데이터가 제대로 삭제되는지 확인해보겠습니다.

❓ 세션이 사라지지 않았습니다

세션이 남아있다세션 안에 있는 데이터를 지웠다는 다른 것이기 때문입니다.
세션은 저장소일 뿐이라 그 안의 추가적인 데이터와는 다릅니다. 따라서 세션 저장소가 남아 있을수도 있지만 그 안에 있는 사용자의 이메일 데이터는 날아갔을 것입니다.


확인해보니 USER_ID키의 데이터는 잘 삭제되었습니다.

세션이 로그인에만 쓰이는 것이 아니기 때문에, 로그아웃을 할 시에 내부에 있는 데이터를 다 날리는 것보다는 저장했던 키와 관련된 데이터만 지우는 것도 하나의 방법이 될 수 있습니다.


만료시간이 지난 후 세션값 조회

처음에 만료시간 이후 데이터가 제대로 삭제되는지 확인하기 위해 앱단에@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 60)으로 지정한 후 테스트해보았습니다.

처음에 조회된 데이터

만료시간(1분) 이후 조회된 데이터


1분이 지나도 spring:session:sessions가 남아있었습니다. 그 이유를 스프링 공식문서에서 발견할 수 있었습니다.

즉, 코드상으로 만료시간을 60초로 지정하면 spring:session:sessions:expires에는 60초로 설정되고, spring:session:sessions에는 5분을 더한 6분이 만료시간으로 설정됩니다. 그 이유는 세션 세부 데이터가 세션 만료시간(1분)에 삭제되는 순간에도 필요하기 때문에 5분의 시간이 더 주어지는 것입니다.


6분 후에 해당 세션 데이터가 삭제된 것을 확인하였습니다.


후기

처음에 keys * 명령어로만 정보를 확인하였기 때문에 데이터가 지워지지 않은줄 알았지만, 아니었습니다. redis에 세션데이터가 어떻게 저장되는지 확인해보면서 저장소에 대한 개념을 다시 확인할 수 있었고, 어떤 데이터가 저장되는지 알 수 있어서 이후 다른 필요한 데이터도 사용할 수 있을 것입니다.



📕Reference

https://redis.io/commands
https://docs.spring.io/spring-data/redis/docs/current/api/org/springframework/data/redis/core/RedisTemplate.html
https://docs.spring.io/spring-session/docs/2.2.x/reference/html/api.html

profile
열심히 공부중입니다😇

1개의 댓글

comment-user-thumbnail
2022년 6월 10일

프로젝트에 많은 도움이 되었습니다 감사합니다!

답글 달기