본문 바로가기

Computer Science

Redis는 어떻게 key를 expire 하는가?

Redis에서는 key에 timeout을 설정할 수 있다. 이 경우, timeout이 지난 key는 만료(expire) 되어 redis에서 삭제된다. 이전 회사에 다니던 시절에 Redis로 key에 timeout을 걸어줘야 하는 작업을 하면서 이 기능이 어떤 원리로 동작하는지에 대해 의문을 품고 찾아봤던 일이 있었다. 이와 관련하여 지금은 조금 여유가 생겨 간략히 글을 남겨본다.

 

Key가 만료되었는지 확인하고, 삭제할 수 있는 가장 간단한 전략으로는 다음의 두 가지를 생각해 볼 수 있다:

  1. eager way: 주기적으로 전체 key들을 살펴보며 timeout에 도달했는지 체크해보고, 도달한 경우 key를 삭제한다.
  2. lazy way: 어떠한 key에 대한 접근이 이루어지는 시점에 timeout에 도달했는지 체크해보고, 도달한 경우 key를 삭제한다.

두 방법에는 모두 장/단점이 있는데, 1번 방법의 경우 매번 전체 key들을 살펴봐야한다는 단점이 있고, 반대로 2번 방법의 경우 매번 전체 key들을 살펴볼 필요는 없지만, 실제 접근이 이루어지기 전 까지는 만료된 key들이 메모리 상에 공간을 차지하고 계속 남아있다는 단점이 있다.

 

Redis에서는 이러한 단점들을 보완하기 위해 2번 전략을 기본으로 가져가되, 1번 전략을 다음과 같이 수정하여 사용한다. 구체적으로는, 다음의 과정을 1초에 10번 수행한다.

  • 랜덤으로 20개의 key를 뽑아 살펴보며 timeout에 도달했는지 체크해보고, 도달한 경우 key를 삭제한다. 만약, 25% 이상의 key가 timeout에 도달한 경우, 다시 이 과정을 반복한다.

구현 디테일을 보고 싶다면, 아래의 소스코드를 참고하면 된다.

https://github.com/redis/redis/blob/unstable/src/expire.c

 

GitHub - redis/redis: Redis is an in-memory database that persists on disk. The data model is key-value, but many different kind

Redis is an in-memory database that persists on disk. The data model is key-value, but many different kind of values are supported: Strings, Lists, Sets, Sorted Sets, Hashes, Streams, HyperLogLogs,...

github.com

Redis의 EXPIRE 명령어에 대해 자세히 알고 싶다면, 아래의 공식 문서 링크를 참고하면 된다.

https://redis.io/commands/expire/