본문 바로가기
문제 해결, 기술 비교/개인프로젝트(북클럽)

Redis eviction 정책은 무엇을 사용해야 할까?

코동이 2022. 9. 28.

개요


Redis를 통해 캐시하는 작업을 공부했습니다. 그렇다면 자연스럽게 드는 생각은, Redis의 메모리가 다 차면 이후에 어떻게 삭제(eviction)해야할까? 입니다. 삭제에는 다양한 정책이 있으며 이는 Redis의 장점이기도 합니다. 이번 시간에는 다양한 redis의 삭제 전략을 알아보고 최적의 선택을 해보겠습니다.

 

 

maxmemory 설정하기


maxmemory 설정은 Redis가 사용할 메모리 양의 최대치를 정하는 것입니다. Redis가 캐시로 사용될 때 새로운 데이터가 추가되면 오래된 데이터는 자동으로 삭제되도록 하는 설정이 일반적입니다. (memcached도 이런 방식을 사용합니다.) Redis의 경우에는 다양한 정책을 가질 수 있으므로 종류와 설정법을 알아보겠습니다.

maxmemory는 redis.conf 파일이나 CONFIG SET 명령어를 통해서 설정합니다.

예를 들어, 메모리를 100mb로 제한하고 싶다면 redis.conf에 다음처럼 설정하면 됩니다

maxmemory 100mb


maxmemory를 0으로 설정하면 메모리 제한이 없어집니다. 32bit는 기본으로 3GB의 메모리 제한이 있지만, 64bit는 기본으로 메모리 제한이 없으므로 설정이 필요합니다.

 

 

Eviction(삭제) 정책 알아보기


메모리 사용이 최대에 근접할 때, 삭제 정책에 따라서 동작이 달라집니다. 만약 메모리 사용이 최대치를 초과한다면 Redis는 에러를 반환하거나, 새로운 데이터가 추가되는 때마다 한계치를 넘지 않기 위해 오래된 데이터를 삭제 할 수 있습니다.

 

크게 3가지로 구분지을 수 있는데 문단으로 나눴습니다.

 

noeviction: 메모리가 한계치에 이르면, 새로운 값이 저장되지 않습니다. 데이터베이스 레플리카를 사용하면, 프라이머리 데이터베이스에 적용됩니다

allkeys-lru: 최근에 사용할수록 오래 보관합니다; 가장 사용이 오래된 것을 제거합니다
allkeys-lfu: 많이 사용할수록 오래 보관합니다; 가장 사용 빈도수가 적은 것을 제거합니다
allkeys-random: 새로 추가되는 데이터를 위해서 기존 데이터에서 무작위로 제거합니다

 

volatile-lru: expire가 true로 설정된 키 중, 가장 사용이 오래된 것을 제거합니다
volatile-lfu: expire가 true로 설정된키 중, 가장 사용 빈도수가 적은 것을 제거합니다
volatile-random: expire가 true로 설정된 키 중, 무작위로 제거합니다
volatile-ttl: expire가 true로 설정된 키 중, 제거합니다. 또한 가장 ttl 값이 작은 것을 제거합니다

 

 

 

Eviction(삭제) 작동 방식


1. 클라이언트는 명령어를 실행하고 데이터를 추가한다
2. Redis는 메모리 사용량을 체크하고, maxmemory 한계치보다 넘어선다고 판단하면,  

    정책에 따라서 일부 데이터를 삭제한다
3. 새로운 명령어가 실행되고 검사가 반복된다

따라서 계속 메모리 한계를 확인하고, 데이터를 추가하고, 키를 삭제하는 과정이 반복됩니다.

 

 

어떤 정책을 사용해야 할까?


eviction 정책의 선택은 어플리케이션에서 캐시로 설정한 데이터에 접근 방식에 따라서 다릅니다. 어플리케이션이 작동하는 중간인 런타임에 정책을 재설정할 수 있습니다. Redis INFO를 사용해 캐시 미스를 모니터링 할 수 있습니다.

 

저는 페이징 되는 게시판을 조회할 때를 예시로 고민하고 있습니다. 어떻게 하면 사용자들에게 응답속도를 더 높일 수 있을까요?

 

volatile-* 정책은 주의해야 하는데, expire라는 별도의 데이터는 메모리를 점유합니다. 따라서, allkeys 정책이 훨씬 메모리 효율이 좋습니다. 또한 volatile-* 정책들은 삭제 할 키가 없다면 noeviction 정책으로 작동합니다.

 

allkeys-random의 경우는 모든 데이터가 순회 접근방식으로 조회가 되는 경우 사용되면 효과적입니다. 왜냐하면 모든 키에 접근 빈도가 비슷하기 때문입니다. 이는 일정 페이징만 접근하는 경우에는 어울리지 않습니다.

 

allkeys-lfu는 빈도수가 중요합니다. 물론 캐시 기준에서 빈도수가 중요할 수 있지만 빈도수를 기준으로 하면 이는 특정 사용자들만 고려한 것입니다. 특정 사용자가 아닌 일반 전체 사용자들의 기준은 일반적으로 최신의 데이터를 보는 것이 더 많을 것입니다.

 

결론적으로 allkeys-lru를 사용합니다. allkeys-lru는 최근에 사용했는지가 중요합니다. 사람들은 일반적으로 글을 볼 때, 최신의 글부터 봅니다. 특정 사람들을 제외하고는 최신정보를 보는 것이 일반적이기 때문에, 최근일수록 접근성이 좋을 것이고 캐시 효과가 날 것입니다.

 

정책은 아래와 같이 설정 할 수 있습니다.

 

maxmemory-policy allkeys-lru

 

 

참고


https://redis.io/docs/manual/eviction/

반응형