LFU Eviction (Least Frequently Used)캐시란 무엇인지, 어떤 상황에서 캐시를 사용해야 하는지, 레디스를 캐시로 잘 사용하는 방법과 주의해야 할 점까지 설명한다. 캐시와 비슷한 다른 세션 스토어에 대해서도 알아보자.
캐시란?
캐시는 데이터를 임시로 저장하여 빠르고 효율적으로 액세스할 수 있게 하는 저장소이다. 동일한 요청에 대해 데이터를 반복적으로 읽는 것이 아니라 캐시에서 데이터를 가져옴으로써 성능을 향상시킬 수 있다.
캐시의 장점
- 빠른 데이터 접근: 원본 데이터 저장소보다 빠르게 데이터에 접근할 수 있다.
- 데이터 변경이 적음: 자주 변경되지 않는 데이터일 때 유용하다.
- 높은 접근 빈도: 자주 접근하는 데이터에 적합하다.
캐싱 읽기 전략(Look Aside)
- 개념: 애플리케이션이 데이터를 읽을 때, 먼저 캐시를 확인하여 필요한 데이터가 캐시에 있는지 확인한다. 캐시에 데이터가 있으면 이를 사용하고, 없으면 원본 데이터베이스에서 데이터를 가져와 캐시에 저장한 후 사용한다. 이를 "캐시 히트"와 "캐시 미스"로 구분한다.
- 캐시 히트: 요청한 데이터가 캐시에 존재하는 경우.
- 애플리케이션이 데이터를 요청하면 캐시를 먼저 확인한다.
- 캐시에 요청한 데이터가 있으면 캐시에서 데이터를 읽어 반환한다.
- 예: 사용자가 프로필 정보를 요청할 때, 캐시에 프로필 정보가 있으면 바로 반환.
- 캐시 미스: 요청한 데이터가 캐시에 존재하지 않는 경우.
- 애플리케이션이 데이터를 요청하면 캐시를 먼저 확인한다.
- 캐시에 요청한 데이터가 없으면 원본 데이터베이스에서 데이터를 가져온다.
- 가져온 데이터를 캐시에 저장한 후, 애플리케이션에 반환한다.
- 예: 사용자가 프로필 정보를 요청했으나 캐시에 해당 정보가 없으면 데이터베이스에서 가져와 캐시에 저장하고 반환.
- 캐시 히트: 요청한 데이터가 캐시에 존재하는 경우.
- 장점: 필요한 데이터만 캐시에 저장하여 메모리 사용을 최적화할 수 있다. 캐시 미스가 발생하는 경우에만 원본 데이터베이스에 접근하므로, 불필요한 데이터베이스 접근을 줄일 수 있다.
- 단점: 캐시 미스가 발생할 때 원본 데이터베이스에 접근하는 시간이 소요될 수 있다. 이로 인해 초기 요청 시 응답 시간이 길어질 수 있다.
예시 시나리오
- 웹 애플리케이션: 사용자가 자주 접근하는 데이터를 캐시에 저장하여 빠른 응답을 제공.
- 전자상거래 사이트: 제품 정보나 가격 데이터를 캐시에 저장하여 사용자가 빠르게 접근할 수 있도록 함.
- 소셜 미디어 플랫폼: 사용자 프로필이나 피드 데이터를 캐시에 저장하여 빠른 읽기 성능 제공.
미리 데이터베이스에서 캐시로 데이터를 밀어넣는 작업을 해주기도 하는데, 이를 캐시 워밍(Cache warming)이라고 한다.
상품이 오픈하기 전 데이터베이스에 저장된 데이트를 레디스로 밀어넣는 작업이 예에 해당한다.
캐싱 쓰기 전략
캐싱 쓰기 전략은 데이터베이스와 캐시 간의 데이터 일관성과 성능을 관리하는 방법을 정의한다. 만약 읽기 작업과 쓰기 작업간에 동기화 문제가 생기면 정합성이 증명되지 않은 데이터를 읽어갈 수 있다. 이를 캐시 불일치(cache inconsistancy) 라고 한다.
이를 해결하기 위해 적절한 캐싱 쓰기 전략을 사용하여야 하며 대표적인 캐싱 쓰기 전략으로는 Write Through, Write Behind (Write Back), Cache Invalidation이 있다. 각 전략의 특징과 작동 방식을 요약하면 다음과 같다.
Write Through
- 개념: 데이터베이스에 데이터를 쓸 때마다 캐시에도 동시에 데이터를 쓰는 방식이다.
- 작동 방식:
- 애플리케이션이 데이터를 쓰면, 캐시에 먼저 쓰고 데이터베이스에도 쓴다.
- 항상 캐시와 데이터베이스의 데이터가 일관성을 유지한다.
- 장점: 데이터 일관성이 보장된다.
- 단점: 데이터 쓰기 작업이 두 번 수행되므로 성능이 저하될 수 있다.
- 사용 예: 금융 시스템 등 데이터 일관성이 중요한 경우.
Cache Invalidation
- 개념: 데이터베이스의 데이터가 변경될 때 캐시의 데이터를 무효화하여 일관성을 유지하는 방식이다.
- 작동 방식:
- 데이터베이스의 데이터가 변경되면 해당 데이터와 관련된 캐시 항목을 무효화한다.
- 무효화된 캐시 항목에 대한 요청이 들어오면, 데이터베이스에서 최신 데이터를 가져와 캐시에 저장한다.
- 장점: 캐시의 데이터가 항상 최신 상태로 유지된다.
- 단점: 무효화 작업이 빈번하게 발생하면 성능이 저하될 수 있다.
- 사용 예: 뉴스 사이트 등 데이터 변경이 빈번하고 최신 데이터 유지가 중요한 경우.
Write Behind (Write Back)
- 개념: 캐시에서 데이터가 변경되면 일정 시간 후 또는 특정 조건에 따라 한꺼번에 데이터베이스에 쓰는 방식이다.
- 작동 방식:
- 애플리케이션이 데이터를 캐시에 쓴다.
- 일정 시간 후 또는 특정 조건이 충족되면 캐시의 데이터를 데이터베이스에 쓴다.
- 장점: 데이터베이스의 쓰기 작업을 줄여 성능을 향상시킬 수 있다.
- 단점: 캐시의 데이터가 데이터베이스와 일시적으로 불일치할 수 있다.
- 사용 예: 로그 기록 시스템 등 쓰기 빈도가 높고 일관성 요구가 상대적으로 낮은 경우.
캐시에서의 데이터 흐름
기본적으로 레디스는 데이터를 메모리에 보관하기 때문에 서버의 스토리지보다 훨씬 적은 양을 보관할 수 밖에 없다. 따라서 일정 데이터를 유지해야하며 계속해서 새로운 데이터가 저장되고 기존 데이터는 삭제될 수 있도록 적절한 TTL값을 지정하는 것이 좋다.
만료 시간(TTL - Time To Live)
Redis에서 특정 키에 대해 유효 기간(만료 시간)을 설정하여 데이터가 일정 시간이 지나면 자동으로 삭제되도록 한다. 이는 메모리 사용을 효율적으로 관리하는 데 도움을 준다.
SET key value # key에 value를 설정한다
EXPIRE key seconds # key의 만료 시간을 seconds초로 설정한다
TTL key # key의 남은 만료 시간을 초 단위로 반환한다
TTL 커맨드를 사용하면 키에대한 만료 시간을 확인할 수 있는데, 만료 시간이 남아있다면 남은 시간을 반환하며 키가 존재하지 않을때는 -2를, 키에 대한 만료 시간이 지정되지 않았다면 -1을 반환한다.
만료 시간은 일반적으로 초(second) 단위로 설정되며, 특정 키에 대한 만료 시간이 설정되면 해당 키와 관련된 데이터는 설정된 시간이 지나면 자동으로 삭제된다. 이를 통해 Redis에서는 일시 데이터의 유효 기간을 정의하고, 오래된 데이터를 자동으로 정리할 수 있다.
메모리 관리와 maxmemory-policy 설정
Redis는 메모리 사용을 관리하기 위해 maxmemory 설정과 다양한 정책(maxmemory-policy)을 제공한다. 메모리가 부족해지면 설정된 정책에 따라 데이터를 삭제한다.
maxmemory <bytes> # Redis가 사용할 최대 메모리 크기를 설정한다
maxmemory-policy noeviction # 메모리가 부족할 때 데이터를 삭제하지 않고 오류를 반환한다
maxmemory-policy allkeys-lru # 모든 키에 대해 LRU(Least Recently Used) 알고리즘을 사용하여 데이터를 삭제한다
maxmemory-policy volatile-lru # 만료 시간이 설정된 키에 대해서만 LRU 알고리즘을 사용하여 데이터를 삭제한다
maxmemory-policy allkeys-random # 모든 키 중에서 무작위로 데이터를 삭제한다
maxmemory-policy volatile-random # 만료 시간이 설정된 키 중에서 무작위로 데이터를 삭제한다
maxmemory-policy volatile-ttl # 만료 시간이 가장 가까운 키를 우선 삭제한다
LRU Eviction (Least Recently Used)
가장 오랫동안 사용되지 않은 데이터를 삭제하여 메모리를 확보하는 알고리즘이다. Redis는 allkeys-lru와 volatile-lru 두 가지 정책을 제공한다.
maxmemory-policy allkeys-lru # 모든 키에 대해 LRU 알고리즘을 사용하여 데이터를 삭제한다
maxmemory-policy volatile-lru # 만료 시간이 설정된 키에 대해서만 LRU 알고리즘을 사용하여 데이터를 삭제한다
LFU Eviction (Least Frequently Used)
가장 적게 사용된 데이터를 삭제하여 메모리를 확보하는 알고리즘이다. Redis는 allkeys-lfu와 volatile-lfu 두 가지 정책을 제공한다.
maxmemory-policy allkeys-lfu # 모든 키에 대해 LFU 알고리즘을 사용하여 데이터를 삭제한다
maxmemory-policy volatile-lfu # 만료 시간이 설정된 키에 대해서만 LFU 알고리즘을 사용하여 데이터를 삭제한다
Random Eviction
메모리가 부족할 때 무작위로 데이터를 삭제하는 방법이다. Redis는 allkeys-random과 volatile-random 두 가지 정책을 제공한다.
maxmemory-policy allkeys-random # 모든 키 중에서 무작위로 데이터를 삭제한다
maxmemory-policy volatile-random # 만료 시간이 설정된 키 중에서 무작위로 데이터를 삭제한다
volatile-ttl
만료 시간이 가장 가까운 키를 먼저 삭제한다. 이는 만료 시간이 설정된 키에만 적용된다.
maxmemory-policy volatile-ttl # 만료 시간이 가장 가까운 키를 우선 삭제한다
캐시 스탬피드 현상

캐시 스탬피드 현상은 여러 클라이언트가 동시에 캐시에 접근하여 만료된 데이터를 갱신하려고 할 때 발생하는 문제로, 서버에 과부하를 초래할 수 있다. 캐시의 특정 키가 만료되었을 때 여러 클라이언트가 동시에 데이터베이스에 요청을 보내는 상황에서 주로 발생한다.
결과적으로 데이터베이스에 과도한 부하가 걸리며, 이는 성능 저하와 서비스 장애로 이어질 수 있다. 이러한 문제를 해결하기 위해 적절한 만료 시간 설정과 선 계산(pre-computation) 기법을 사용하여 데이터를 미리 갱신하거나 만료 시간을 동적으로 조정할 수 있다.
캐시 스탬피드 현상을 예방하는 방법: 선 계산 (Pre-computation)
데이터가 만료되기 전에 미리 계산하여 캐시에 저장하는 방법이다. 이는 여러 클라이언트가 동시에 데이터를 갱신하려고 할 때 발생하는 부하를 줄인다.
def fetch(key):
value = redis.get(key)
if not value:
value = db.fetch(key)
redis.set(key, value)
return value
위의 코드는 데이터를 캐시에서 먼저 찾고, 없으면 데이터베이스에서 가져와 캐시에 저장하는 방식이다. 이를 통해 캐시 스탬피드를 줄일 수 있다.
캐시 스탬피드 현상을 예방하는 방법: PER 알고리즘
PER(Probabilistic Early Recomputing) 알고리즘은 캐시 값이 만료되기 전에 미리 값을 재계산하여 데이터베이스에 접근해야 하는 상황을 줄이는 것이 목표다. PER 알고리즘의 작동 원리는 다음과 같다
currentTime - ( timeToCompute * beta * log(rand()) ) > expiry
속성 | 설명 |
currentTime | 현재 남은 만료 시간 |
timeToCompute | 캐시된 값을 다시 계산하는 데 걸리는 시간 beta: 기본적으로 1.0으로 설정되며, 큰 값으로 설정할 수 있음 rand(): 0과 1 사이의 랜덤 값을 반환하는 함수 |
beta | 기본적으로 1.0으로 설정되며, 큰 값으로 설정할 수 있음 |
rand | 0과 1 사이의 랜덤 값을 반환하는 함수 |
expiry | 키를 재설정할 때 새로 넣어줄 만료 시간 |
이 조건을 만족할 때마다 데이터를 다시 계산하여 캐시에 저장한다. 이 알고리즘은 만료 시간이 가까워질수록 true를 반환할 확률이 증가하므로, 불필요한 재계산을 효과적으로 방지한다.
세션으로의 레디스
참고 자료
개발자를 위한 레디스 | 김가림 - 교보문고
개발자를 위한 레디스 | 개발자가 인메모리 데이터베이스인 레디스를 잘 활용할 수 있도록 초점을 맞춘 포괄적인 안내서다. 레디스를 처음 배우는 독자나 NoSQL 데이터베이스의 개념을 쌓고자 하
product.kyobobook.co.kr
GitHub - redis/redis-doc: Redis documentation source code for markdown and metadata files, conversion scripts, and so forth
Redis documentation source code for markdown and metadata files, conversion scripts, and so forth - redis/redis-doc
github.com
'기술 탐구 > redis' 카테고리의 다른 글
Redis는 I/O 이벤트 통지 메커니즘, epoll에 대해 알아보자 (0) | 2025.04.03 |
---|---|
(Redis) 레디스 자료 구조 활용법 (사례) (0) | 2024.06.25 |
(Redis) Redis의 자료 구조와 Key 관리 명령어 (0) | 2024.06.18 |