세션
- 서버는 쿠키에 담긴 Session ID를 클라이언트로부터 받아 이를 DB에 저장한다.
- Stateless를 유지하는 방법으로 사용된다.
JSESSIONID
Tomcat에서 관리하며, 세션을 먼저 조회한 후 데이터를 전달한다.
서버 확장 방법
- Scale-Up: 서버 사양을 올리는 방식이지만 한계가 있고 비용이 많이 든다.
- Scale-Out: 서버 대수를 늘리고 로드 밸런서를 통해 요청을 분산한다. 현재 많이 사용되는 방법이다.
Sticky Session
- 부하분산기 사용 시, 한 클라이언트의 요청을 항상 같은 서버로 보낸다.
- 문제점
서버 고정으로 인해 부하 분산이 불가능하고, 해당 서버가 다운되면 사용자 정보 손실 가능성이 있다.
세션 클러스터링
외부 저장소에 세션 정보를 저장하고 공유하여 Sticky Session 문제를 해결한다.
- 장점: 사용량 증가 시 Scale-Out이 용이하다.
- 단점: 외부와의 통신으로 인해 지연이 발생할 수 있다.
Redis 사용
JSESSIONID
대신SESSION
을 사용하여 Spring Data Session에서 관리하게 변경한다.- Redis에 저장된 세션은 기본적으로 바이트 코드이며, 보기 좋게 하려면 JSON으로 직렬화할 수 있다. security 사용시 문제가 발생할 수 있다.
- Java 직렬화를 사용해도 동작에는 문제가 없다.
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return RedisSerializer.java();
}
Redis, Sorted Set
- 사용 사례
게임 순위, 실시간 검색어, 인기 상품 등 - 문제점
RDBMS로 집계 쿼리 작성 시 조인, 정렬, 리미트 등으로 인해 성능 저하가 발생할 수 있다. - 해결 방법
Redis의 Sorted Set을 사용한다.- 인메모리 데이터 저장으로 파일 I/O 레이턴시 문제를 해소할 수 있다.
- 시간 복잡도: ZADD -
O(logN)
, ZRANGE -O(log(n) + m)
- 간단하고 효율적이다.
캐싱
- Cache: CPU가 자주 사용하는 값을 보관하는 저장소
- 관계형 데이터베이스: 영속성 데이터를 저장하는 파일 시스템
- RAM: 휘발성 저장소
브라우저 캐시
- 브라우저에서 서버로 데이터를 반복적으로 주고받는 대신 캐시에 저장하여 효율성을 높인다.
- RESTful API의 Cacheability 설정:
Cache-Control
을 통해 응답 데이터의 캐시 가능 여부를 설정할 수 있다.
캐싱 기본 용어
- Cache Hit: 캐시에 접근했을 때 데이터가 존재한다.
- Cache Miss: 캐시에 접근했을 때 데이터가 존재하지 않는다.
- Eviction Policy: 캐시 공간이 부족할 때 공간 확보 방식이다.
- Caching Strategy: 캐시 적중률(Hit)을 높이고 누락률(Miss)을 줄이는 전략이다.
캐싱 전략
Cache-Aside 전략 (Lazy Loading)
데이터가 캐시에 없을 때 캐시에 추가하고, 있으면 반환한다.
- 장점: 첫 요청 이후부터 빠르다.
- 단점: 최신 데이터를 보장하기가 어렵다.
Write-Through 전략
데이터를 추가할 때 캐시에 먼저 추가하고, 그다음 관계형 데이터베이스에 저장한다.
- 장점: 최신 데이터를 보장하고, 읽기 성능이 빠르다.
- 단점: 자주 사용하지 않는 데이터도 저장하며, 속도가 느릴 수 있다.
Write-Behind 전략
캐시에만 저장하고 일정 횟수 이후 관계형 데이터베이스에 한번에 저장한다.
- 장점: 데이터베이스 부하 감소시킬 수 있다.
- 단점: 캐시가 원본 데이터 적용 전에 삭제되면 데이터 유실 가능성이 존재한다.