포스트

2022-06-28-TIL

Today I Learned

Redis 자꾸 로그아웃 되는 문제

로그인 세션을 Redis에 저장하는 구조에서 사용자가 자꾸 로그아웃된다면, 세션 데이터가 기대보다 일찍 사라졌거나 애플리케이션이 그 세션을 찾지 못한 것이다. 아래 두 글을 참고해 이 문제를 볼 때 확인할 지점을 정리했다. 지금은 두 글 모두 열리지 않아 링크만 남겨 둔다.

세션 만료 시간

Spring Session으로 세션을 Redis에 저장한다면 먼저 세션 만료 시간을 본다. Spring Boot 문서에 따르면 세션 타임아웃은 spring.session.timeout으로 정하고, 이 값이 없으면 서블릿 웹 애플리케이션에서는 server.servlet.session.timeout 값을 쓴다. 의도한 것보다 짧게 잡혀 있으면 사용자가 잠깐 자리를 비운 사이에 세션이 만료된다.

1
spring.session.timeout=30m

Redis 메모리와 eviction 정책

Redis는 maxmemory에 도달하면 maxmemory-policy에 따라 키를 지운다(Redis eviction 문서). 세션 키에는 만료 시간(TTL)이 걸려 있으므로, 다음 정책에서는 메모리가 부족할 때 세션 키가 먼저 지워질 수 있다.

  • volatile-lru: TTL이 있는 키 중 가장 오래 쓰지 않은 것을 지운다.
  • volatile-ttl: TTL이 있는 키 중 남은 시간이 가장 짧은 것을 지운다.
  • allkeys-lru: TTL과 상관없이 가장 오래 쓰지 않은 키를 지운다.

캐시 데이터와 세션을 한 Redis에 함께 두면, 캐시가 메모리를 채우는 순간 세션까지 밀려날 수 있다. INFO memory로 현재 메모리 사용량이 maxmemory에 가까운지 먼저 확인한다. 세션처럼 잃으면 안 되는 데이터는 캐시와 다른 Redis 인스턴스에 두는 편이 안전하다.

같은 Redis를 쓰는 다른 애플리케이션

Spring Session 문서는 여러 애플리케이션이 같은 Redis 인스턴스를 쓰는 일이 드물지 않아서, 세션 데이터를 구분하도록 네임스페이스(기본값 spring:session)를 둔다고 설명한다. 서로 다른 애플리케이션이 같은 네임스페이스를 쓰면 세션이 섞이거나 덮어써질 수 있으므로 애플리케이션마다 다르게 지정한다.

1
spring.session.redis.namespace=spring:session:myapplication

연결 문제

Redis 연결을 얻지 못해 세션 조회가 실패해도 사용자 입장에서는 로그아웃처럼 보인다. Jedis를 쓴다면 풀에서 빌린 연결을 돌려주지 않아 풀이 바닥나는 경우가 대표적이다. 애플리케이션 로그에 연결 관련 예외가 함께 찍혀 있는지 본다.

  • https://overfloweb.tistory.com/184
  • https://blooog.tistory.com/entry/Redis-Jedis-%EC%82%AC%EC%9A%A9-%EC%8B%9C-%EA%B2%AA%EC%97%88%EB%8D%98-%EB%AC%B8%EC%A0%9C
참고한 자료외부 출처 3

외부 출처

이 글은 저작권자의 CC BY 4.0 라이선스를 따릅니다.

댓글

아직 댓글이 없습니다