세션 클러스터링
세션 클러스터링은 다중 서버 환경에서 세션 데이터를 서버 간에 복제·공유하여, 어떤 서버로 요청이 가더라도 동일한 세션 정보를 유지할 수 있게 하는 기술입니다.
왜 필요한가?
서버가 여러 대일 때 세션은 기본적으로 해당 서버의 메모리에만 저장되므로, 다른 서버로 요청이 라우팅되면 세션을 찾지 못하는 세션 불일치 문제가 발생합니다.
[문제 상황]
1. 클라이언트 → 서버A : 로그인 → 서버A 메모리에 세션 저장
2. 클라이언트 → 서버B : 마이페이지 요청 → 세션 없음 → 로그인 풀림 X
세션 불일치 해결 방법 3가지
1. Sticky Session
로드밸런서가 같은 클라이언트의 요청을 항상 같은 서버로 보내는 방식입니다.
클라이언트 → 로드밸런서 → 항상 서버A로 고정
| 장점 | 단점 |
|---|---|
| 구현이 간단 | 특정 서버에 트래픽 집중 가능 |
| 세션 복제 비용 없음 | 해당 서버 장애 시 세션 유실 |
2. 세션 클러스터링 (Session Clustering)
서버 간에 세션 데이터를 복제하여 모든 서버가 동일한 세션을 보유하는 방식입니다.
서버A ←세션 복제→ 서버B
↕ ↕
서버C ←세션 복제→ 서버D
→ 어떤 서버로 요청이 가도 세션 조회 가능 O
Tomcat의 경우 DeltaManager 또는 BackupManager를 통해 클러스터링을 지원합니다.
All-to-All 복제
모든 서버가 모든 세션을 보유
- 장점: 어디서든 즉시 조회 가능
- 단점: 서버 수가 늘수록 복제 비용 급증 (N대 → N-1번 복제)
Backup 복제 (Primary-Secondary)
세션을 생성한 서버(Primary)와 지정된 백업 서버(Secondary)만 보유
- 장점: 복제 대상이 줄어 네트워크 부담 감소
- 단점: Primary + Secondary 동시 장애 시 유실 가능
3. 외부 세션 저장소 (Session Storage)
세션을 서버 메모리가 아닌 Redis, Memcached 같은 외부 저장소에 저장하는 방식입니다. 현업에서 가장 많이 사용됩니다.
서버A ─┐
서버B ─┼─→ Redis (세션 저장소)
서버C ─┘
// Spring Boot + Redis 세션 저장소 설정
// build.gradle
implementation 'org.springframework.session:spring-session-data-redis'
// application.yml
spring:
session:
store-type: redis
redis:
host: localhost
port: 6379
// 기존 코드 변경 없이 그대로 사용 가능
@GetMapping("/mypage")
public String myPage(HttpSession session) {
String user = (String) session.getAttribute("loginUser");
// 세션이 Redis에서 자동으로 조회됨
return "mypage";
}
3가지 방식 비교
| 항목 | Sticky Session | 세션 클러스터링 | 외부 세션 저장소 |
|---|---|---|---|
| 세션 위치 | 개별 서버 메모리 | 모든(또는 일부) 서버 메모리 | Redis 등 외부 저장소 |
| 서버 확장 | 제한적 | 서버 증가 시 복제 부담 | 자유로움 O |
| 장애 대응 | 세션 유실 | 복제본으로 복구 가능 | 저장소 장애만 주의 |
| 네트워크 비용 | 없음 | 복제로 인해 높음 | 조회 시 발생 |
| 적합 규모 | 소규모 | 중규모 | 대규모 O |
면접 포인트
- 세션 클러스터링의 핵심 한계는 서버가 늘어날수록 복제 비용이 기하급수적으로 증가한다는 점입니다.
- 그래서 대규모 서비스에서는 세션 클러스터링보다 Redis 기반 외부 세션 저장소를 선호하며, 아예 서버가 상태를 갖지 않도록 JWT 기반의 무상태 인증으로 전환하는 추세입니다.
- Spring 환경에서는
Spring Session + Redis조합으로 코드 변경 없이 외부 세션 저장소를 적용할 수 있습니다.