LabHub
学习 学习路径 课程

Redis 与缓存

处理 TTL 与过期策略

在 LabHub 中继续学习

한국어 원문으로 표시합니다.

목표

TTL 의 동작을 정확히 이해하고, TTL 이 조용히 사라지는 함정을 재현해 막고, 축출 정책의 차이를 실제 축출로 확인한다.

왜 중요한가

"Redis 메모리가 계속 자라는데 원인을 모르겠다"는 문의의 대부분은 TTL 을 안 건 키입니다. 그리고 그것이 눈에 안 띄는 이유는 코드가 SETEX 를 잘 쓰고 있는데도 어딘가에서 SET 으로 값만 갱신하면서 원래 있던 수명을 날려 버리기 때문입니다. 이 실습의 3번 스텝이 정확히 그 장면입니다. 또 하나 몸에 남겨야 할 것은 만료가 즉시가 아니라는 사실입니다. Redis 는 접근할 때 지우거나 백그라운드에서 표본을 뽑아 지웁니다. 그래서 만료 시각이 지난 키가 DBSIZE 에 남아 있을 수 있고, "만료됐는데 왜 메모리가 안 줄지"의 답이 여기 있습니다. 마지막 감사 스크립트는 운영에 그대로 가져가 쓸 수 있는 물건입니다.

단계

  1. cache:a 를 값과 함께 60초 수명으로 넣고 /root/ttl/ttl1.txtttl=<남은초> 를 적는다. 값은 1 이상 60 이하이다.
  2. cache:a 의 TTL 을 제거한다. /root/ttl/ttl2.txtttl=-1 이 적혀야 한다.
  3. cache:b 를 60초 수명으로 넣은 뒤 SET cache:b <새값> 으로 값만 갱신한다. TTL 이 -1 이 되는 것을 /root/ttl/lost.txt 에 기록하고, KEEPTTL 로 다시 시도한 결과를 /root/ttl/kept.txtttl=<양수> 로 적는다.
  4. cache:c 를 1초 수명으로 넣고 2초 기다린 뒤, 접근하지 않은 상태의 DBSIZE 와 접근 후의 DBSIZE/root/ttl/lazy.txtbefore=<n> after=<n> 으로 적는다.
  5. maxmemory-policyallkeys-lfu 로 설정한다. /root/ttl/policy.txtmaxmemory-policy allkeys-lfu 가 들어가야 한다.
  6. maxmemory 를 8mb 로 낮추고 /root/ttl/fill.py 로 키를 충분히 넣어 축출을 일으킨다. /root/ttl/evicted.txtevicted_keys=<n> 을 적고 n 은 0보다 커야 한다.
  7. /root/ttl/audit.shSCAN 순회하며 TTL 이 -1 인 키를 /root/ttl/nottl.txt 에 적는다. 스크립트에 KEYS 문자열이 있으면 안 되고, 결과 파일에 최소 1개의 키가 있어야 한다.

참고

TTL 걸고 남은 수명 확인하기

cache:a 를 값과 함께 60초 수명으로 넣고 /root/ttl/ttl1.txtttl=<남은초> 를 적는다. 값은 1 이상 60 이하이다.

수명을 함께 지정해 넣는 명령도 있고, 이미 있는 키에 거는 명령도 있습니다. 남은 수명을 조회해 보세요.

TTL 제거해 영구 키로 만들기

cache:a 의 TTL 을 제거한다. /root/ttl/ttl2.txtttl=-1 이 적혀야 한다.

TTL 이 없는 키의 조회 결과는 -1 입니다. -2 는 다른 뜻이니 주의하세요.

SET 이 TTL 을 날리는 함정 재현하고 막기

cache:b 를 60초 수명으로 넣은 뒤 SET cache:b <새값> 으로 값만 갱신한다. TTL 이 -1 이 되는 것을 /root/ttl/lost.txt 에 기록하고, KEEPTTL 로 다시 시도한 결과를 /root/ttl/kept.txtttl=<양수> 로 적는다.

값만 갱신했는데 수명이 사라집니다. 수명을 유지하는 옵션이 있습니다.

만료가 즉시 메모리 반환이 아님을 관찰하기

cache:c 를 1초 수명으로 넣고 2초 기다린 뒤, 접근하지 않은 상태의 DBSIZE 와 접근 후의 DBSIZE/root/ttl/lazy.txtbefore=<n> after=<n> 으로 적는다.

만료 시각이 지났는데 아무도 접근 안 한 키는 한동안 남아 있습니다. 조회 전후로 개수를 비교해 보세요.

축출 정책 설정하기

maxmemory-policyallkeys-lfu 로 설정한다. /root/ttl/policy.txtmaxmemory-policy allkeys-lfu 가 들어가야 한다.

기본값은 캐시 용도에 맞지 않습니다. 캐시 전용이라면 어떤 정책이 좋을지 읽기 자료를 참고하세요.

실제로 축출이 일어나게 만들기

maxmemory 를 8mb 로 낮추고 /root/ttl/fill.py 로 키를 충분히 넣어 축출을 일으킨다. /root/ttl/evicted.txtevicted_keys=<n> 을 적고 n 은 0보다 커야 한다.

메모리 한도를 작게 잡고 키를 많이 넣으면 됩니다. 축출 통계는 INFO 에 있습니다.

TTL 없는 키 감사 스크립트 만들기

/root/ttl/audit.shSCAN 순회하며 TTL 이 -1 인 키를 /root/ttl/nottl.txt 에 적는다. 스크립트에 KEYS 문자열이 있으면 안 되고, 결과 파일에 최소 1개의 키가 있어야 한다.

SCAN 으로 순회하며 남은 수명이 -1 인 키를 모읍니다. 운영에서 주기적으로 돌릴 수 있는 형태여야 합니다.