로컬 캐시(Local Cache) vs 글로벌 캐시(Global Cache)
캐시는 크게 **로컬 캐시(Local Cache)**와 **글로벌 캐시(Global Cache)**로 구분됩니다. 각 유형은 데이터가 어디에 저장되고 어떤 방식으로 접근 가능한지에 따라 다릅니다.
1. 로컬 캐시 (Local Cache) - 공유X
로컬 캐시는 개별 서버 또는 애플리케이션 인스턴스의 메모리 내에서 작동하는 캐시입니다. 이 캐시는 데이터 접근 속도가 빠르지만, 여러 인스턴스 간의 데이터 공유가 어렵습니다.
특징
- 위치: 캐시가 애플리케이션이 실행 중인 서버 내부(메모리나 디스크)에 저장됩니다.
- 속도: 서버 메모리를 직접 사용하므로 매우 빠릅니다.
- 격리: 각 서버가 독립적으로 데이터를 캐싱하며, 다른 서버와 캐시 데이터를 공유하지 않습니다.
- 적합한 상황:
- 단일 서버에서만 동작하는 애플리케이션.
- 데이터가 자주 변하지 않으며 인스턴스 간 공유가 필요 없는 경우.
장점
- 빠른 데이터 접근: 네트워크를 거치지 않고 로컬 메모리에서 데이터를 가져오기 때문에 성능이 우수.
- 간단한 구조: 외부 시스템과의 통합 없이 간단하게 구현 가능.
단점
- 데이터 일관성 문제: 여러 서버가 같은 데이터를 캐싱할 경우, 각 서버의 데이터가 달라질 수 있음.
- 메모리 제한: 서버의 메모리 크기에 따라 저장 가능한 데이터의 양이 제한됨.
예시
- Spring Framework의 @Cacheable: Spring에서 로컬 캐시로 애노테이션 기반 캐싱을 설정하면, 서버의 JVM 메모리 내에 캐시 데이터를 저장.
- Ehcache: 자바 애플리케이션 내에서 사용할 수 있는 고성능 로컬 캐시 라이브러리.
2. 글로벌 캐시 (Global Cache) - 공유O
글로벌 캐시는 애플리케이션 서버와 별도로 분리된 외부 시스템에서 운영되며, 여러 서버 또는 인스턴스 간에 데이터를 공유할 수 있는 캐시입니다.
특징
- 위치: 독립된 캐시 서버(예: Redis, Memcached)나 분산 캐시 시스템에 저장.
- 속도: 네트워크를 통해 접근하므로 로컬 캐시보다는 느리지만, 여러 서버 간의 데이터 일관성을 유지.
- 적합한 상황:
- 여러 서버나 애플리케이션 인스턴스가 동일한 데이터를 공유해야 하는 경우.
- 클라우드 기반 분산 시스템처럼 다수의 노드에서 데이터를 처리해야 하는 경우.
장점
- 데이터 일관성: 모든 서버가 동일한 데이터를 참조하므로 데이터 불일치 문제를 해결.
- 확장성: 캐시 서버를 수평적으로 확장(Scaling) 가능.
- 다중 플랫폼 지원: 다양한 애플리케이션과 서버에서 같은 캐시를 사용할 수 있음.
단점
- 네트워크 지연: 캐시 서버와의 네트워크 통신이 필요하므로 로컬 캐시보다 느림.
- 복잡성 증가: 외부 시스템을 설정하고 유지보수해야 하며, 장애가 발생하면 의존하는 애플리케이션도 영향을 받을 수 있음.
예시
- Redis: 분산 환경에서 사용되는 대표적인 글로벌 캐시 솔루션. Key-Value 데이터 저장, TTL(Time-To-Live) 설정 가능.
- Memcached: 빠르고 경량화된 글로벌 캐시 시스템으로, 주로 데이터베이스 부하를 줄이기 위해 사용.
- AWS ElastiCache: 클라우드 기반 글로벌 캐시 서비스로, Redis나 Memcached를 지원.
3. 로컬 캐시와 글로벌 캐시를 함께 사용하는 전략
대규모 시스템에서는 로컬 캐시와 글로벌 캐시를 조합하여 성능과 확장성을 동시에 고려합니다.
- 글로벌 캐시를 기본 데이터 저장소로 사용하면서, 각 서버의 로컬 캐시에서 자주 사용하는 데이터를 캐싱하여 성능을 최적화합니다.
- 예:
- 글로벌 캐시(예: Redis)에서 데이터를 읽어온 후, 이를 로컬 캐시(예: JVM 메모리)에 저장. 이후 동일한 요청은 로컬 캐시에서 바로 처리.
- 실제 사례: 사용자 인증 토큰 캐싱
- 글로벌 캐시: Redis에 저장된 사용자 인증 토큰을 여러 서버에서 참조.
- 로컬 캐시: 서버 메모리에 최근 사용자 인증 토큰을 저장하여 추가 요청을 빠르게 처리.
사용법
Spring boot의 @cacheable
의존성 추가:
implementation 'org.springframework.boot:spring-boot-starter-cache'
@EnableCaching 추가 및 빈 등록
*스프링은 다양한 캐시 매니저를 제공하고 있습니다.
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("suggestionList");
}
}
@Cacheable 추가: 클래스나 인터페이스에도 캐시를 지정할 수는 있지만, 일반적으로 메소드 단위로 적용합니다.
@Cacheable(value = "suggestionList")
public List<FindPeriodTradeSuggestionResDto> findPeriodTradesSuggestion(Long tradeId) {
return getPeriodTradeSuggestions(tradeId);
}
@Cacheable
@Cacheable(value = "suggestionList", key = "#book.bookNo", condition = "#user.type == 'ADMIN'")
public List<FindPeriodTradeSuggestionResDto> findPeriodTradesSuggestion(Long tradeId) {
// ...
return getPeriodTradeSuggestions(tradeId);
}
출처 : https://mangkyu.tistory.com/179
key: 여러 개의 파라미터 중에서도 1개의 키 값으로 지정하고 싶을 때
condition: 파라미터 값이 특정 조건인 경우에만 캐시를 적용하고 싶을 때
@Cacheable을 사용하는 경우, 캐시 저장소에 저장된 데이터가 RDB 데이터와 불일치할 가능성이 있습니다. 특히, 업데이트가 다른 API에서 수행되었다면 캐시에 저장된 데이터가 업데이트 사실을 반영하지 못할 수 있습니다. 이를 보완하기 위해 @CacheEvict, @CachePut 을 사용할 수 있습니다.
@CacheEvict
: 업데이트나 삭제 API에서 데이터 변경이 발생했을 때 관련 캐시를 무효화하도록 @CacheEvict를 설정합니다.
@CacheEvict(value = "myCache", key = "#id")
public void updateData(Long id, MyEntity updatedData) {
// RDB에 데이터 업데이트
myRepository.save(updatedData);
}
@CachePut
: 캐시를 무효화하는 대신 @CachePut을 사용하여 캐시의 데이터를 직접 업데이트할 수도 있습니다.
@CachePut(value = "myCache", key = "#id")
public MyEntity updateData(Long id, MyEntity updatedData) {
// RDB에 데이터 업데이트
return myRepository.save(updatedData);
}
그외 cache 와 DB 데이터의 불일치 해결 방법
**캐시 TTL 설정**
: 캐시 데이터가 오래되지 않도록 TTL(Time-To-Live)을 설정하여, 일정 시간이 지나면 자동으로 무효화되게 합니다.
- 장점: 추가적인 무효화 작업 없이 캐시 데이터가 갱신됩니다.
- 단점: TTL 내의 데이터는 여전히 일관성이 보장되지 않을 수 있습니다.
**캐시 이벤트 기반 동기화**
RDB 데이터가 업데이트되었을 때 캐시를 동기화하는 이벤트 기반 설계를 사용할 수 있습니다. 이를 위해 다음과 같은 기술을 사용할 수 있습니다:
- Redis Pub/Sub: 데이터 변경 시 관련 캐시 키를 무효화하도록 메시지를 발행.
- Spring Events: Spring의 이벤트 시스템을 사용하여 변경 이벤트를 캐시에 전달.
**Write-Through/Write-Behind 캐시 패턴**
- Write-Through: 데이터 변경 시 캐시와 RDB를 동시에 업데이트.
- Write-Behind: 데이터 변경 시 캐시를 먼저 업데이트하고, 이후 RDB를 비동기로 업데이트.
- 장점: 데이터 일관성을 유지하면서 캐시 성능을 활용.
- 단점: 설계 및 구현 복잡도가 증가.
Redis:
https://tes1194.tistory.com/174
Redis란 무엇일까? + lock을 이용한 동시성 제어
Redis 란 무엇일까?Key, Value 구조의 정형화 되지 않은 데이터를 저장하고 관리하기 위한 오픈 소스 기반의 비관계형 데이터 베이스 관리 시스템. In memory Key-Value NoSQL. DISK DBMS에서는 매번 디스크에
tes1194.tistory.com