효율적인 캐시 띄우기를 위한 Redis Eviction 정책

허진혁·2023년 6월 6일
0

🤔 고민 사항

캐시 저장소로 redis를 사용하고, Spring Cache를 도입하여 읽기 작업의 성능을 높이는 작업을 진행했어요. 하지만 데이터 관리를 제대로 하지 않는다면 문제가 발생해요. 심지어 서버가 죽어버리고, 그렇다면 캐시를 사용하기 전과 다를게 없어져요.

🛎 예를 들어, SNS 서비스를 많은 사용자가 이용한다고 가정하면, 많은 캐시가 서버에 가득차게 되요. 이 때, 메모리 사용을 제한하지 않으면 캐시 데이터는 계속 쌓일 것이고, 메모리를 계속 차지하게 되어 애플리케이션 성능에 영향을 줄 수도 있어요. 그래서 Redis에서 지원하는 다양한 Eviciton 정책을 알아보고 적합한 방식을 적용해 볼거에요.

레디스의 메모리 관리 방법

Redis는 메모리에 데이터를 저장하기 때문에 물리메모리(RAM) 용량보다 더 많은 데이터를 사용하게 될 경우 메모리 부족으로 인해 swap이 발생하여 Redis의 성능 저하를 일으킬 수 있어요.

위 [그림2]와 같이 데이터를 물리 메모리의 용량보다 더 많은 데이터가 들어오면, swap이 발생하는 것을 볼 수가 있어요. 운영체제에서 Swap space의 주요 기능은 물리메모리(RAM)의 양이 가득 차고 더 많은 메모리의 양이 필요할 때 Backing store(디스크)의 가상메모리에 대체하게 되요.

Setting maxmemory to zero results into no memory limits. This is the default behavior for 64 bit systems, while 32 bit systems use an implicit memory limit of 3GB.

Redis 공식문서에 따르면 기본 용량은 32bit 시스템에서 3GB로 제한이 있지만, 64Bit에서는 제한이 없어요.

따라서, 스왑 영역까지 사용하지 않기 위해 다음과 같이 설정이 필요해요. Redis가 사용할 메모리의 용량을 제한하기 위해 redis.conf 파일의 maxmemory 옵션으로 지정하면 되요.

maxmemory 100mb

Redis는 이러한 메모리 관리를 통해 메모리의 양을 그 이상의 범위를 사용하지 않도록 제한할 수 있어요. 또한, Redis를 In-memory 데이터 저장소로 사용하며 일반적인 디스크 솔루션(RDBMS)에 비해 적은 양의 데이터를 저장함해요. 최대치로 저장하게 되면 Redis 메모리에 새로운 데이터가 들어오게 되고, 기존의 데이터는 제거되는 방식이 필요해요. 이것을 eviction이라고 부르는데, 이러한 방식을 만들기 위해 “maxmemory-policy”옵션을 통해 eviction 정책을 만들 수 있어요.

Eviction Policy

  • noeviction: maxmemory에 도달하면 쓰기/삭제 작업시 오류를 반환합니다.
  • allkeys-lru: 새로 추가된 데이터의 용량을 확보하기 위해 최근에 사용하지 않은 키를 제거합니다.
  • volatile-lru: 새로 추가된 데이터의 용량을 확보하기 위해 TTL이 설정된 키들 중 최근에 사용하지 않은 키를 제거합니다.
  • allkeys-lfu: 새로 추가된 데이터의 용량을 확보하기 위해 사용빈도수가 가장 적은 키를 제거합니다.(최근 저장된 키라도 사용 빈도수가 적다면 대상이 될 수 있습니다.)
  • volatile-lfu: 새로 추가된 데이터의 용량을 확보하기 위해 TTL이 설정된 키들 중 사용빈도 수가 적은 키를 제거합니다. (최근 저장된 키라도 사용 빈도수가 적다면 대상이 될 수 있습니다.)
  • allkeys-random: 새로 추가된 데이터의 용량을 확보하기 위해 무작위로 키를 제거합니다.
  • volatile-random: 새로 추가된 데이터의 용량을 확보하기 위해 TTL이 설정된 키들 중 무작위로 키를 제거합니다.
  • volatile-ttl: 새로 추가된 데이터의 용량을 확보하기 위해 TTL이 짧은 키를 제거합니다.

어플리케이션 특성에 맞게 Eviction 정책을 선택하여 redis.conf 파일의 maxmemory-policy 옵션에 지정하면 되요.

💊 어떤 Eviction 정책이 적합할까?

SNS 서비스를 많은 사용자들이 이용하는 상황을 가정하고 있어요. 그만큼 빠르게 증가하는 캐시 데이터를 효율적으로 관리하면서도 요청이 많은 데이터를 선별적으로 보존할 필요가 있어요.

❌ 먼저, noeviction 과 volatile- 정책들은 적합하지 않다고 판단했어요. noeviction 정책은 기존의 데이터를 삭제하지 않는다는 특징은 데이터 보존이 목적인 서비스에 적합하다고 판단했어요.
volatile- 정책들은 "TTL(만료시간이 존재해야함)"라는 전제 조건을 만족한 데이터들만 제거 대상으로 되요. 만약 전제 조건을 만족하는 데이터들이 없다면 noeviction 정책처럼 처리되기 때문에 선택하지 않았어요.

나머지 allkeys-lru, allkeys-random, allkeys-lfu 중에서
👍 저는 allkeys-lfu 정책을 선택했어요.

allkeys-lru 는 최근에 사용했는지에 따라 데이터 보존 여부가 나누어요. 사람들이 잘 찾지 않는 리소스더라도 어떤 사람이 최근에 요청했다면 삭제 대상에서 제외될 거에요. 즉, 재요청될 가능성이 높은 데이터가 순위에 밀려 삭제가 될 수 있어요. 요청이 많이 들어오는 데이터가 삭제된다면 그만큼 데이터베이스에 접근하는 횟수가 높아질 가능성이 있다는 거에요.

✅ 따라서, allkeys-lfu 정책을 적용하여 위와 같은 문제 상황이 없도록 했다.

참고자료

Redis
Redis eviction policy를 사용하여 효율적으로 레디스 사용하기
Redis 내부 동작 원리와 최적화 방안 - 에스코어

profile
Don't ever say it's over if I'm breathing

0개의 댓글