지금까지 Redis의 개념, 자료구조, 캐싱 전략, 아키텍처, 영속성까지 정리했습니다.
이제 마지막으로
실무에서 Redis를 운영할 때 반드시 알아야 하는 장애 포인트와 운영 전략
을 정리해 보겠습니다
Redis는 매우 빠르고 강력하지만 잘못 사용하면 서비스 전체 장애를 유발할 수 있는 위험한 시스템이기도 합니다.
Redis 운영 시 위험한 명령어

Redis는 Single Thread 기반으로 동작합니다 그래서
하나의 무거운 명령어가 실행되면
전체 요청이 Block 될 수 있습니다.
레디스가 명령어를 처리하는 방법을 간단하게 알아보자면 Packet들 이 Redis의 processInputBuffer에 전해지면 그곳에서 packet들이 모여 하나의 Commnad를 만들게 되고 process Command에서 실제 동작을 수행하게 됩니다
이렇듯 하나의 Commnad를 실행하는 동작이 오래 걸리게 되면 뒤에 계속 Packet이 쌓이게 되고 다른 명령어는 아무런 동작을 하지 않은 채 그저 기다리고만 있습니다
이렇게 시간이 많이 걸리는 명령어들을 빅 O 표기법에서 O(n)의 시간이 걸려 O(n) 명령어 라고 합니다
이제 그 명령어의 종류와 이 명령어를 우회하는 방법을 알아보겠습니다
O(n) 명령어 - KEYS
KEYS *
이 명령어는 전체 키를 반환하는 동작을 하는데 내부 동작으로는 전체 키를 전부 순회하는 FullScan 방식으로 동작합니다
그렇기 때문에 빅 O표기법에 따라 O(n) 시간이 걸리게 됩니다
예를 들어 Key 가 100만 개 존재한 상황에서 Keys 커맨드를 실행하면 Redis 수 초 ~ 수십 초 멈출 수 있습니다
이는 곧
- API Timeout
- 장애 발생 가능
와 같은 심각한 문제로 이어질 수 있습니다
대체 방법 — SCAN

keys 명령어의 대체 방법으론 scan 방식입니다
key 방식이 한 번에 존재하는 모든 key를 다 가져오는 방식이었다면
Scan 방식은 커서방식으로 짧게 여러 번 돌려서 key들을 가져오는 방식입니다. 여기서 중요한 점은 이 짧게 여러 번이라는 것입니다
짧게 여러 번 가져오기 때문에 한 번의 동작사이의 잠깐의 시간들이 존재하고,
그 시간들 덕분에 다른 명령어들이 수행할 수 있습니다
O(n) 명령어 - Delete Collections
Collection에 아이템이 몇백 개 있을 때는 delete 하면 상관없는데
만일 몇십만 개면? → 동작이 1,2초 걸리고 그때 동안 다른 커맨드 들은 아무것도 못하고 기다리게 됩니다
즉 Delete는 Collection에 Item을 지우는 명령어로 O(n)의 시간을 가지며 , Collection 내부의 아이템 수에 따라 성능이 크게 좌우됩니다.
대체 방법 - unlink del
unlink del
일반적으로 DEL 명령어로 키를 지우게 되면 그 키를 지우는 동안 아무런 동작을 할 수 없었습니다.
이때 UNLINK 커맨드를 사용한다면, key를 백그라운드로 지워주기 때문에 KEY를 지우는 동안에 다른 동작을 할 수 있게 됩니다
O(n) 명령어 - Get Collections
어떤 collection을 사용하든 Collection 내부에 10만 개의 item을 가져오려면 당연히 느려지게 됩니다
이럴 때는 여러 개의 우회 방법을 사용할 수 있습니다
대체 방법
1. 키 나누기
하나의 키에 아이템을 최대 100만 개 정도까지만 들고 있게 키를 분배합니다
2. hgetall → hscan
getall로 모든 아이템을 한 번에 다 가져오는 것이 아니라 scan을 이용해 짧게 여러 번 가져올 수 있도록 합니다
메모리 관리
이전까지 사용하지 않아야 하는 명령어를 배워봤으므로 이번에는 메모리 관리 측면에서 정리를 해보겠습니다
Redis는 In-Memory Data Store입니다 그래서 Physical Memory 이상을 사용하면 문제가 발생합니다.
Swap을 사용한다 해도 해당 메모리 Page 접근 시마다 늦어지게 됩니다.
또한 Max memory를 설정하더라도 이보다 더 사용할 가능성이 있습니다
이렇듯 다른 어떤 툴보다 메모리 관리가 매우 중요한 게 Redis입니다 이는 곧 성능으로 이어지기 때문입니다
메모리 관리 - Ziplist 활용
이전에 많은 Collection을 배웠습니다. 이 Collection을 사용할 때 내부에서 사용하는 자료구조는 다음과 같습니다
- Hash → HashTable을 하나 더 사용
- Sorted Set → Skiplist와 Hash
- Set → HashTable 사용
이렇듯 Collection 자료 구조를 그대로 사용하게 되면 우리가 생각한 것보다 메모리를 더 많이 쓰게 됩니다
왜냐하면 해당 자료구조를 구현하기 위해서 포인터 등등 여러 가지 다양한 이유가 있기 때문입니다
이를 해결하고자 등장한 게 ziplist입니다
ZipList

ZipList는 특정 알고리즘을 사용하는 게 아니라 그림에서 보는 것과 같이 선형으로 아이템을 저장합니다
zipList가 Redis에서 특히 의미가 있는 이유는 Redis는 인메모리다 보니깐 적당한 사이즈 까지는 특정 알고리즘을 안 쓰고 풀 서치를 하더라도 빠르게 쓸 수 있기 때문입니다
그런데 너무 많은 아이템을 넣으면 원래 자료구조로 바뀌어서 속도는 유지하지만 메모리를 더 많이 사용할 수도 있습니다.
ZipList 설정법
따라서 Collection에 들어가는 Item이 몇십~ 몇백 개 정도이면 Collection을 사용할 때 기본으로 제공하는 자료구조 대신 ZipList를 쓰라고 설정할 수 있습니다
즉 collection을 사용할 때 내부적으로 ziplist를 사용하도록 설정을 할 수 있습니다
설정방법은 다음과 같습니다
hash-max-ziplist-entries , has-max-zioplist-value
list-max-ziplist-size , list-max-ziplist-value
zset-max-ziplist-entries, zset-max-ziplist-value
해당 설정을 통해 최대 몇 개 까지 ziplist를 사용할지 , 어떤 자료구조에서 사용할지 설정할 수 있습니다
이를 통해 메모리를 아껴봅시다!
모니터링
이렇듯 Redis는 메모리 관리가 매우 중요합니다
그래서 메모리를 잘 사용하고 있는지 모니터링을 가져가는 게 중요합니다 이때 관측 지표에 대해서 정리해보고자 합니다

used_memory : 논리적으로 redis가 사용하는 메모리…
used_memory_rss : os가 redis에 얼만큼 메모리를 할당 했는지를 보여준다
모니터링을 할 때 userd memory는 논리적으로 redis 가 사용하는 메모리입니다.
즉 우리가 계산을 할 때 아 이 정도쯤 사용하겠지 하는 그 사용량이 이 관측 값에 해당이 됩니다
하지만 OS 가 Redis에 메모리를 할당할 때 에는 이렇게 딱 딱 맞게 메모리를 주는 게 아니라 Block 단위를 줍니다
예를 들어 우리는 7 정도의 메모리 사용을 예상했지만 실제 OS는 정책에 따라 30 씩 메모리를 잘라서 Redis에 제공을 합니다
만일 31의 정도 메모리를 쓴다고 가정하면 31만 할당하는 게 아닌 60을 할당받게 됩니다
이를 잘 보여주는 지표가 바로 used_memory_rss 지표입니다
그래서 userd_memory와 used_memory_rss 간의 차이가 클 때 fragmentation(파편화)이 발생했다고 합니다
이 파편화는 주로 삭제되는 키가 많을 때 증가 하게 됩니다
예를 들어 특정 시점에 피크를 찍고 다시 삭제하는 경우, TTL로 인한 Eviction 이 발생하는 경우 가 많아지면 그만큼 파편화도 많이 생깁니다
메모리 관리가 무엇보다 중요한 Redis에서 이러한 파편화는 정말 성능을 크게 좌우합니다
해결법
이를 해결하기 위해선
CONFIG SET activedefrag yes
설정을 활용하면 좋습니다
이걸 켜면 파편화를 제거를 해주는데 Redis 공식 문서에 따르면 이 값을 항상 켜두는 것보다는 단편화가 많이 발생했을 때 켜두는 것도 공식문서에서 권장한다고 되어있습니다
따라서 항상 키지 말고 모니터링을 보고 used_memory와 rss 값의 차이가 크다면 사용하면 좋을 것 같습니다
이외 모니터링 지표들
Redis를 모니터링할 때 추가로 더 확인하면 좋을 것을 정리해 보겠습니다
- Redis Info를 통한 정보
- RSS
- Used Memory
- Connection 수
- 초당 처리 요청 수
- System
- CPU
- DISK
- Network rx/tx
CPU 가 100%를 치면?
좀 더 CPU 성능이 좋은 단일 코어로 서버를 이전하는 게 좋습니다
O(N) 계열 명령어가 많은 경우?
아주 짧게 Monitor 명령을 통해 특정 패턴을 파악하는 것이 필요합니다 근데 주의할 건 이 명령어를 아주 짧게 써야 합니다 잘못 쓰
면 부하로 해당 서버에 더 큰 문제를 일으킬 수 있습니다
권장 설정
마지막은 Redis를 운영할 때 권장할 설정을 알아보겠습니다
만일 영구 저장을 사용한다면?
STOP-WRITES=ON=BGSAVE-ERROR = NO
yes가 default인데 이는 = RDB 파일 저장 실패 시 redis로 들어오는 모든 write를 차단하겠다 를 의미합니다
그래서 redis 서버에 대한 기능의 모니터링을 적절히 한다면, 이 기능을 끄는 게 불필요한 장애를 막을 수 있습니다
만일 영구 저장을 사용하지 않는다면?
1. Maxclient 설정 50000
2. RDB/AOF 설정 off
3. 특정 commands disable ( keys 같은 것)
4. ziplist 설정
5. MAXMEMORY-POLICY = ALLKEYS-LRU 설정
전체 장애의 90% 이상이 KEYS와 SAVE(영구저장 관련) 설정을 사용해서 발생한다고 합니다 이를 방지하기 위해 위에 5가지 설정을 꼭 해주는 걸 권장합니다
추가로 MAXMEMORY-POLICY에 대해서 간단하게 정리하게 마무리하겠습니다
MAXMEMORY-POLICY
redis를 캐시로 사용할 때는 expire time 설정을 권장합니다.
아무래도 메모리가 한정되어 있기 때문에 이 값을 설정하지 않는다면 금세 레디스의 MAX MEMORY까지 데이터가 가득 차게 되기 때문입니다.
이렇게 메모리가 가득 찼을 때 MAXMEMORY-POLICY 정책에 의해 데이터가 삭제되는데 설정 값에 따라 데이터가 삭제될 수도 안될 수도 있습니다
noeviction(default) : 삭제 안함
- 메모리가 가득차면 데이터를입력하는게 불가능하기 때문에 장애로 발생 할 수 있습니다
volatile-lru: lru 정책 즉 가장 최근에 사용하지 않았던 키 부터 삭제한다는것을 의미합니다
이때 expire 설정이 있는 key 값만 삭제한다는것을 의미합니다
- allkeys-lru :
- 추천 설정
- 모든 키에 대해 lru방식으로 키를 삭제하겠다를 의미
- 이걸하면 데이터가 가득 참으로 인해 데이터가 장애가 발생할 가능성이 없습니다
마무리
Redis는 단순히 빠른 캐시 서버가 아니라
운영 전략과 장애 대응 능력이 매우 중요한 시스템입니다.
정리하면
- KEYS 같은 Blocking 명령어 주의
- fork 기반 메모리 폭발 이해
- TTL은 트래픽 제어 도구
- 모니터링은 필수
- 권장 설정
이 개념들을 이해하면
실무에서 Redis를 안정적으로 운영할 수 있을 수 있습니다
이제는 Spring에서 제공하는 RedisTemplate과 활용방법에 대해서 학습해 보겠습니다
'🖥️ 컴퓨터 공부 > Redis' 카테고리의 다른 글
| Spring에서 Redis 쉽게 사용하는 방법 정리 -활용 (0) | 2026.03.21 |
|---|---|
| Spring Data Redis 공식문서로 내부 동작 이해하기 (0) | 2026.03.21 |
| Redis 영속성 & Failover 정리 (RDB / AOF / Failover) (0) | 2026.03.21 |
| Redis 아키텍처 정리 (Replication / Sentinel / Cluster / Sharding) (0) | 2026.03.20 |
| Redis 캐싱 전략 (0) | 2026.03.20 |