기본적으로 HTTP는 상태가 없는(stateless) 프로토콜이기 때문에, 각 요청이 독립적이고 이전의 요청과 관련이 없습니다. 이를 해결하기 위해 쿠키와 세션 개념이 도입되었습니다.
Http Session & Cookie이란❓
HTTP 세션(HTTP Session)은 웹 애플리케이션에서 사용자와의 상호작용을 관리하기 위해 사용되는 기술입니다.
세션의 주요 특징은 다음과 같습니다.
상태 유지
- HTTP 세션은 클라이언트(사용자)와 서버 간의 상태를 유지하여, 사용자가 웹사이트를 탐색할 때 계속해서 정보를 기억하고 활용할 수 있도록 합니다.
세션 식별자
- 세션을 식별하기 위해 보통 세션 ID가 사용됩니다.
- 이 세션 ID는 서버가 생성하여 클라이언트에게 전달하고, 클라이언트는 이후의 요청에 이 ID를 포함시켜 서버가 이를 식별할 수 있도록 합니다.
- 세션 ID는 일반적으로 쿠키를 통해 클라이언트 측에 저장됩니다.
서버 측 저장
- 세션 데이터는 보통 서버 측에서 관리됩니다.
- 사용자가 웹사이트를 탐색하는 동안, 서버는 사용자 쿠키의 세션 ID를 기반으로 세션 데이터를 저장하고, 필요할 때마다 이 데이터를 조회하여 사용자에게 맞는 응답을 제공합니다.
세션 데이터
- 세션에는 로그인 정보, 장바구니의 내용, 사용자 설정 등 사용자가 웹 애플리케이션과 상호작용하면서 생성된 데이터가 포함될 수 있습니다.
세션 만료
- 세션은 일정 시간이 지나면 만료됩니다.
- 이는 사용자가 일정 시간 동안 활동하지 않으면 서버가 세션을 종료시키고 리소스를 해제하는 방식으로 수행됩니다.
세션과 쿠키를 정리하자면 다음과 같습니다.
쿠키(Cookie)
- 클라이언트의 브라우저에 저장되는 작은 데이터 파일로, 세션 ID와 같은 정보를 포함해 서버와의 상태를 유지
세션(Session)
- 서버 측에서 사용자의 상태와 정보를 저장하고 관리하여 웹 애플리케이션의 연속성을 제공
Scale Up & Scale Out이란❓
현대의 IT 환경에서는 애플리케이션과 서비스가 다양한 트래픽 패턴과 데이터 처리 요구를 경험합니다.
특히, 사용자 수가 급격히 증가하거나 데이터 처리량이 많아질 때, 단일 서버로는 모든 요청을 감당하기 어려운 상황이 발생할 수 있습니다. 이러한 문제를 해결하기 위해 시스템의 성능과 확장성을 확보하는 것이 필수적입니다.
이러한 자원 관리 전략에는 Scale Up(수직 확장)과 Scale Out(수평 확장)이 포함됩니다.
Scale Up은 기존 서버의 성능을 향상하기 위해 하드웨어를 업그레이드하는 방법입니다. 이는 더 강력한 CPU, 메모리, 저장 장치 등을 추가하여 단일 서버의 처리 능력을 강화합니다.
반면에, Scale Out은 시스템의 용량을 확장하기 위해 더 많은 서버나 인스턴스를 추가하는 방식입니다. 이렇게 하면 부하를 여러 서버에 분산시켜 시스템의 성능을 향상하고, 높은 가용성을 유지할 수 있습니다.
그러나 Scale Out 방식으로 서버를 늘려 각 서버에 요청을 분산시키는 경우, 한 가지 중요한 의문이 발생할 수 있습니다.
서버가 증가하면 사용자의 세션 데이터는 각 서버에 개별적으로 저장될 수 있는데, 예를 들어 사용자가 A 서버에 요청을 보냈다면 세션 ID는 A 서버에 저장될 것입니다.
이후 사용자가 B 서버로 요청을 보내게 되면, B 서버에는 사용자의 세션 데이터가 없기 때문에 세션이 유지될 수 있는지 위 그림처럼 A서버는 8080 포트, B서버는 8081 포트로 설정하여 직접 확인해 보겠습니다.
Controller
사용할 컨트롤러는 위와 같고, 포트 8080에서 /set? q=value로 요청을 보내서 세션에 값을 저장한 후, /get 요청으로 저장된 값을 확인해 보겠습니다.
포트 8080에서 /set과 /get 요청은 정상적으로 동작하여 세션 값이 저장되고 조회됩니다. 그러나 포트 8081에서 /get 요청을 보내면, 세션 값이 없어서 null이 반환됩니다.
이러한 상황을 해결하기 위한 방법은 Sticky Session과 Session Clustering으로 크게 두 가지가 있습니다.
Sticky Session이란❓
세션 유지
- 클라이언트의 세션 데이터가 특정 서버에 저장된 경우, 이후의 모든 요청이 동일한 서버로 전달되어 세션 정보를 일관되게 유지할 수 있습니다.
로드 밸런서 설정
- 로드 밸런서는 클라이언트의 요청을 특정 서버로 계속 전달하기 위해 세션 ID나 다른 식별자를 사용합니다.
- 이를 통해 세션 데이터가 저장된 서버에 요청을 보내는 것이 가능합니다.
장점
- 세션 데이터 일관성 유지
- 서버가 클라이언트의 세션 정보를 유지하고 있기 때문에, 서버 간 세션 데이터 동기화가 필요 없으므로 일관된 사용자 경험을 제공합니다.
- 단순성
- 세션 정보가 서버에 로컬로 저장되므로, 서버 간 세션 정보 동기화의 복잡성을 피할 수 있습니다.
단점
- 부하 집중
- 특정 서버에만 요청이 집중되면 해당 서버에 부하가 증가할 수 있으며, 이로 인해 서버의 성능 저하나 다운 타임이 발생할 수 있습니다.
- 확장성 문제
- 서버를 추가하거나 제거할 때 스티키 세션을 유지하기 어려울 수 있으며, 확장성에 제한이 있을 수 있습니다.
Session Clustering이란❓
세션 클러스터링은 여러 서버가 협력하여 세션 정보를 공유하고 관리하는 기술로, 세션의 일관성과 가용성을 높이기 위해 사용됩니다.
주로 분산 환경에서 서버가 늘어나는 경우, 클러스터 환경에서 세션 정보를 중앙 집중식으로 저장하거나 동기화하여 시스템의 안정성과 확장성을 개선합니다.
중앙 집중식 세션 저장소
- 세션 클러스터링에서는 세션 정보를 서버의
로컬 저장소가 아닌 외부 저장소나 중앙 저장소에 저장합니다. - 예시: Redis, Memcached, 데이터베이스 등의 외부 저장소에 세션 정보를 저장합니다.
서버 간 세션 동기화
- 서버 간에 세션 정보를 동기화하여, 어떤 서버에서 요청을 처리하든지 동일한 세션 데이터를 사용할 수 있도록 합니다.
- 이를 통해 서버가 추가되거나 제거되더라도 세션 정보가 유지됩니다.
장점
- 높은 가용성
- 서버가 추가되거나 제거되더라도 세션 정보가 중앙 저장소에 저장되므로, 세션이 사라지지 않으며 시스템의 가용성이 높아집니다.
- 유연한 확장성
- 서버 수를 자유롭게 조절할 수 있으며, 부하 분산을 효율적으로 관리할 수 있습니다.
- 균등한 요청 분산
- 세션 정보를 외부 저장소에서 조회하기 때문에, 요청이 어떤 서버로 가든지 세션 데이터에 대한 일관성을 유지할 수 있습니다.
단점
- 관리 포인트 증가
- 세션 정보를 외부 저장소에 저장함으로써 추가적인 관리 포인트가 생깁니다.
- 통신 지연
- 외부 저장소와의 통신에서 지연이 발생할 수 있습니다. 이 문제를 최소화하기 위해 인메모리 데이터베이스(Redis 등)를 사용하는 경우가 많습니다.
Redis에서 Session Clustering 사용하기
의존성 추가
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.session:spring-session-data-redis'
}
Spring Boot와 Redis를 함께 사용하고 있다면, 매우 쉽게 Session Clustering을 적용할 수 있습니다.
세션 클러스터링을 설정한 경우, 세션 데이터가 Redis와 같은 외부 저장소에 저장되기 때문에, 같은 도메인 내의 여러 서버 간에 세션 정보가 공유됩니다.
따라서, 위와 같이 사용자가 요청을 어떤 서버로 보내더라도 세션 정보는 Redis에 저장되기 때문에 일관되게 유지됩니다. 이는 동일 도메인 내에서의 세션 관리 문제를 해결할 수 있습니다.
Redis 데이터를 확인해 보면 세션 데이터가 정상적으로 생성된 것을 확인할 수 있습니다. 그러나 Java의 직렬화 방식 때문에 데이터가 바이너리 형식으로 저장됩니다. 이로 인해 데이터가 사람이 읽기 어려운 형태로 저장될 수 있습니다.
RedisSerializer의 json() 메서드는 Jackson을 사용하여 객체를 JSON 형식으로 직렬화하는 RedisSerializer를 생성합니다.
이 방법은 세션 데이터를 JSON 형식으로 저장하게 해 주며, 이를 통해 데이터의 가독성을 높일 수 있습니다.
'Database > redis' 카테고리의 다른 글
[Redis] Spring boot에서의 Redis사용하기 #2 : RedisTemplate (0) | 2024.08.10 |
---|---|
[Redis] Spring boot에서의 Redis사용하기 #1 : RedisRepository (0) | 2024.08.10 |
[Redis] Redis의 주요 타입 살펴보기 (0) | 2024.08.08 |
[Redis] 인메모리 저장소와 redis란 무엇일까❓ (0) | 2024.08.06 |