Redis big key 문제는 메모리 그래프 하나로만 보이면 자꾸 헷갈립니다. 실제 운영에서는 element 수가 너무 많은 key, 메모리를 지나치게 많이 쓰는 key, 그리고 그 둘이 겹치는 key가 서로 다른 방식으로 사고를 만듭니다. 프로덕션에서 Redis slow log를 보다가 HGETALL이 200ms 넘게 걸리는 걸 발견한 적이 있는데, 해당 hash key의 field가 12만 개가 넘어 있었습니다. 메모리 자체는 크지 않았지만, 단일 command 실행 시간이 Redis 전체 응답을 잠그고 있었습니다. 그래서 “가장 큰 key를 지우자”보다 먼저 무엇이 truly expensive한지 나눠서 봐야 합니다.
짧게 말하면 --bigkeys는 cardinality와 구조 복잡도 쪽, --memkeys와 MEMORY USAGE는 실제 메모리 비용 쪽을 보여줍니다. 이 셋을 같이 봐야 data shape 문제를 제대로 설명할 수 있습니다.
이 글이 필요한 상황
아래 중 하나라면 이 글부터 보는 편이 좋습니다.
- Redis memory usage가 계속 높아지는데 어떤 key가 문제인지 모른다
- 특정 command만 느리고 persistence나 replication 비용도 같이 커진다
- 몇 개 key가 유난히 비싸 보이는데 cardinality 문제인지 memory 문제인지 헷갈린다
- cleanup은 해도 비슷한 운영 이슈가 반복된다
bigkeys와 memkeys는 같은 말이 아닙니다
Redis CLI 문서 기준으로 redis-cli --bigkeys는 element 수가 많은 key를 찾는 쪽에 가깝고, redis-cli --memkeys는 메모리를 많이 쓰는 key를 찾는 쪽에 가깝습니다.
이 차이가 실전에서 꽤 중요합니다.
| 관찰 방식 | 주로 알려주는 것 | 놓치기 쉬운 것 |
|---|---|---|
--bigkeys | key의 길이, cardinality, 구조적 복잡도 | 메모리 오버헤드가 큰 key |
--memkeys | 실제 메모리 비용이 큰 key | element 수는 많지 않아도 비싼 구조 |
MEMORY USAGE key | 특정 key의 실제 메모리 사용량 | 전체 분포나 다른 key와 비교 |
즉 list, set, hash, zset이 원소 수 때문에 비싼 경우도 있고, cardinality는 적당해 보여도 실제 메모리 사용량이 큰 경우도 있습니다.
첫 10분 체크
초반에는 아래 네 줄이면 충분합니다.
redis-cli --bigkeys
redis-cli --memkeys
redis-cli --keystats
redis-cli MEMORY USAGE my:key SAMPLES 0
추가로 production 부하가 걱정되면 CLI 문서에 나온 것처럼 -i 0.1로 SCAN 사이에 잠깐 쉬게 할 수 있습니다.
redis-cli --bigkeys -i 0.1
redis-cli --memkeys -i 0.1
경험상 이 4줄을 한 번 돌리는 것만으로도 문제의 80%는 어느 방향인지 가닥이 잡힙니다. 이 단계에서 먼저 답해야 할 질문은 세 가지입니다.
- cardinality가 지나치게 큰 key가 있는가
- 실제 메모리 사용량이 비정상적으로 큰 key가 있는가
- 문제 key가 특정 prefix나 feature에 몰려 있는가
왜 big key가 memory 문제로만 끝나지 않을까요
Redis latency 문서가 강조하듯, 느린 command 하나가 single-threaded Redis 전체를 잠깐 막을 수 있습니다. big key는 그 느린 command를 더 자주 만들 수 있습니다.
대표적인 영향은 아래와 같습니다.
- 큰 collection을 건드리는 command가 오래 걸린다
- replication과 persistence 비용이 커진다
- eviction pressure가 더 거칠게 드러난다
- hot key 하나가 전체 latency 체감을 왜곡한다
즉 big key는 저장 용량 문제이기도 하지만, 동시에 command shape 문제이기도 합니다.
이런 패턴이면 big key를 의심하세요
아래 조합이 자주 같이 보입니다.
HGETALL,LRANGE,SMEMBERS,ZRANGE같은 넓은 조회가 느리다SLOWLOG에 특정 key family를 건드리는 command가 반복된다- AOF rewrite나 RDB save 구간에 더 괴롭다
- memory는 높고, 지워도 같은 key family가 다시 커진다
이 패턴이면 개별 incident보다 data shape가 반복적으로 문제를 만드는 쪽일 가능성이 큽니다.
MEMORY USAGE는 샘플링 옵션까지 같이 보세요
Redis 공식 문서 기준으로 MEMORY USAGE는 nested type에 대해 SAMPLES 옵션을 받을 수 있고, 기본 샘플 수는 5입니다. 더 정확하게 보고 싶다면 SAMPLES 0으로 전체를 기준 삼아 볼 수 있습니다.
redis-cli MEMORY USAGE cart:123 SAMPLES 0
redis-cli MEMORY USAGE timeline:user:42 SAMPLES 0
특히 “원소 수는 그리 많지 않아 보이는데 왜 이렇게 비싸지?” 같은 질문을 할 때 유용합니다.
흔한 잘못된 시작
아래 대응은 자주 보이지만 보통 첫 단계로는 비효율적입니다.
KEYS *로 전체를 뒤지는 것--bigkeys만 보고 메모리 문제까지 다 설명됐다고 생각하는 것- 가장 큰 key를 바로 삭제하는 것
maxmemory만 늘리면 끝날 문제라고 보는 것
특히 KEYS는 Redis latency 문서에서도 production에서 흔한 latency 원인으로 경고하는 패턴이라 피하는 편이 낫습니다.
실전 점검 순서
1. --bigkeys와 --memkeys를 둘 다 돌립니다
cardinality와 메모리 비용을 분리해서 봐야 합니다.
2. --keystats나 MEMORY USAGE로 실제 무게를 확인합니다
문제 key를 추측이 아니라 수치로 좁혀야 합니다.
3. 그 key를 건드리는 command family를 확인합니다
SLOWLOG나 app trace를 같이 보면 원인이 더 빨리 보입니다.
4. retention, sharding boundary, object shape를 다시 봅니다
진짜 해결은 cleanup보다 구조 변경인 경우가 많습니다.
5. persistence와 latency 부작용까지 다시 확인합니다
메모리 그래프만 좋아졌다고 사건이 끝난 것은 아닐 수 있습니다.
구조 변경이 필요한 대표 패턴
아래 중 하나면 redesign이 더 근본적인 경우가 많습니다.
- 하나의 key가 tenant 전체 데이터를 다 들고 있다
- time window가 너무 길어서 계속 누적된다
- 한 번 조회할 때 매번 너무 많은 data를 만진다
- Redis가 원래 갖고 있지 않아도 되는 materialized blob을 오래 들고 있다
이때 자주 쓰는 방향은 아래입니다.
- tenant, 날짜, object boundary 기준으로 쪼개기
- retention을 강하게 제한하기
- summary와 raw data를 분리하기
- Redis 대신 다른 저장소나 다른 캐시 shape를 쓰기
체크리스트
--bigkeys와--memkeys결과를 둘 다 봤다MEMORY USAGE ... SAMPLES 0으로 실제 비용을 샘플링했다- 문제 key family를 건드리는 command 패턴을 알고 있다
- retention이나 key boundary를 바꿀 수 있는지 검토했다
- persistence와 latency까지 함께 다시 확인했다
FAQ
Q. big key는 메모리 문제만 일으키나요?
아니요. memory, latency, persistence, eviction behavior를 함께 흔드는 경우가 많습니다.
Q. 가장 빠른 첫 단계는 무엇인가요?
--bigkeys와 --memkeys를 같이 돌려서 cardinality 문제와 memory 문제를 분리해 보세요.
Q. 가장 큰 key를 그냥 지우면 되나요?
애플리케이션 영향과 재생성 경로를 이해한 경우에만 그렇습니다. 구조가 그대로면 다시 생깁니다.
Q. 언제 redesign이 불가피한가요?
같은 key family가 반복해서 memory와 latency incident를 만드는 패턴일 때입니다.
Read Next
- write가 거절될 정도라면 Redis OOM Command Not Allowed Guide를 보세요.
Related Posts
Sources:
- https://redis.io/docs/latest/develop/tools/cli/
- https://redis.io/docs/latest/commands/memory-usage/
- https://redis.io/docs/latest/operate/oss_and_stack/management/optimization/latency/
먼저 읽어볼 가이드
검색 유입이 많은 핵심 글부터 이어서 보세요.
- 미들웨어 트러블슈팅 가이드: Redis, RabbitMQ, Kafka 중 어디부터 볼까 Redis, RabbitMQ, Kafka가 함께 있는 시스템에서 지금 보이는 장애가 어느 계층에 더 가까운지, 첫 10분 안에 무엇을 확인하고 어떤 글로 들어가야 하는지 정리한 실전 허브 가이드입니다.
- Kubernetes CrashLoopBackOff: 먼저 볼 것들 startup failure, probe, config, resource limit 관점에서 CrashLoopBackOff를 어떻게 나눠서 봐야 하는지 정리한 가이드입니다.
- Astro 기술 블로그 SEO 체크리스트: 트래픽 기다리기 전에 먼저 고칠 것 Astro 기술 블로그를 위한 실전 SEO 체크리스트입니다. 배포 호스트 확인, robots.txt, sitemap, canonical, hreflang, 구조화 데이터, 페이지별 메타데이터, noindex 판단, 검증 명령까지 우선순위대로 정리합니다.
- 다국어 블로그 canonical과 hreflang 설정 가이드: 무엇을 확인하고 어디서 깨질까 다국어 블로그에서 canonical과 hreflang을 어떻게 설정해야 하는지 실전 기준으로 정리합니다. self-canonical, 상호 연결되는 hreflang 묶음, x-default, 카테고리 페이지, 최종 렌더 HTML 점검, 한 언어 버전이 다른 언어 버전을 눌러버리는 실수까지 다룹니다.
- OpenAI Codex CLI 설치 가이드: 설치, 인증, 첫 작업까지 OpenAI Codex CLI를 실전 기준으로 설치하는 방법을 정리했다. 설치, 로그인, 첫 실행, Windows 주의점, 첫 작업을 어떻게 시작하면 좋은지까지 다룬다.