Redis 모니터링 - 메모리와 성능 지표 완벽 가이드

2025년 12월 05일

monitoring

시리즈모니터링 시리즈#4
# Redis# Monitoring# Grafana# Prometheus

들어가며

Redis는 빠른 응답 속도가 생명인 인메모리 데이터 스토어입니다. 그만큼 메모리 관리와 성능 모니터링이 중요합니다. 이 글에서는 Redis 운영에 필수적인 모니터링 지표들을 정리합니다.

모니터링 아키텍처

Redis → redis_exporter → Prometheus → Grafana
  • redis_exporter: Redis INFO 명령어 결과를 Prometheus 형식으로 변환
  • Prometheus: 메트릭 수집 및 저장
  • Grafana: 시각화 및 알람

핵심 모니터링 지표

실시간 상태 개요 (AWS ElastiCache 기준)

AWS ElastiCache에서 제공하는 주요 메트릭을 기준으로 정리했습니다. 클러스터 모드에서는 각 샤드/노드별로 이 지표들을 비교해야 합니다.

CPU 사용률
45%
EngineCPUUtilization
메모리 사용률
72%
DatabaseMemoryUsagePercentage
캐시 히트율
94.2%
CacheHitRate
스왑 사용량
0MB
SwapUsage
사용 가능 메모리
1.2GB
FreeableMemory
현재 커넥션
156
CurrConnections
Evicted Keys
0
Evictions
단편화 비율
1.12
MemoryFragmentationRatio

1. 메모리 (Memory)

Redis는 인메모리 데이터베이스입니다. 모든 데이터가 RAM에 있어야 하므로 메모리 관리가 운영의 핵심입니다. 메모리가 부족하면 데이터가 삭제되거나(eviction) 최악의 경우 Redis가 죽을 수 있습니다.

🚨

메모리 단편화 비율이 1.0 미만이면 스왑이 발생하고 있다는 의미입니다. Redis가 디스크를 사용하면 성능이 100배 이상 저하됩니다. 즉시 조치가 필요합니다.

두 가지 메모리 지표를 구분해야 합니다:

  • used_memory: Redis가 데이터 저장에 사용하는 논리적 메모리
  • used_memory_rss: OS가 Redis에 실제로 할당한 물리 메모리

메모리 사용량 추이 (2주간)

이커머스 서비스의 전형적인 메모리 패턴입니다. 주중 저녁 피크, 주말 낮 트래픽 증가가 관찰됩니다.

💡

패턴 분석: 금요일 저녁~토요일 오후에 메모리가 최고치를 기록합니다. 이 시간대에 캐시 eviction이 발생하지 않도록 maxmemory 여유를 확보하세요.

클러스터 노드별 메모리 비교 (1주간)

클러스터 모드에서는 샤드 간 메모리 불균형을 모니터링해야 합니다. 핫 키가 특정 샤드에 집중되면 그 노드만 메모리가 빨리 차오릅니다.

⚠️

Shard 1 불균형 감지: Shard 1만 메모리가 급증하고 있습니다. 특정 핫 키(예: 인기 상품 캐시)가 이 샤드에 집중된 것으로 보입니다. 키 분산 전략 검토가 필요합니다.

이 둘의 비율인 메모리 단편화 비율(fragmentation ratio) 이 중요합니다:

비율상태의미
1.0~1.5정상적정 수준의 단편화
1.5 이상주의메모리 낭비, 조사 필요
1.0 미만위험스왑 발생, 즉시 조치
# Redis CLI에서 확인
redis-cli INFO memory

주요 지표:

지표설명의미
used_memory데이터가 사용하는 메모리실제 데이터 크기
used_memory_rssOS가 할당한 메모리실제 물리 메모리 사용량
used_memory_peak최대 메모리 사용량피크 시점 파악
maxmemory설정된 최대 메모리한계치
mem_fragmentation_ratioRSS / used_memory메모리 단편화 정도
⚠️

메모리 사용률이 80%를 넘으면 Warning, 90%를 넘으면 Critical 알람을 설정하세요. eviction이 시작되면 예상치 못한 데이터 손실이 발생할 수 있습니다.

# PromQL - 메모리 사용률
redis_memory_used_bytes / redis_memory_max_bytes * 100

# 메모리 단편화 비율
redis_memory_used_rss_bytes / redis_memory_used_bytes

2. 커넥션 (Connections)

Redis 커넥션은 가볍습니다. 하나의 커넥션당 메모리 오버헤드가 작기 때문에 수천 개의 동시 연결도 처리할 수 있습니다. 하지만 maxclients(기본값 10000)를 초과하면 연결이 거부됩니다.

blocked_clients는 BLPOP, BRPOP 같은 블로킹 명령을 기다리는 클라이언트 수입니다. 메시지 큐 패턴에서는 정상이지만, 예상치 못한 증가는 조사가 필요합니다.

redis-cli INFO clients

주요 지표:

  • connected_clients: 현재 연결된 클라이언트 수
  • blocked_clients: BLPOP 등으로 블록된 클라이언트 수
  • rejected_connections: maxclients 초과로 거부된 연결 수
🚨

rejected_connections가 증가하면 클라이언트가 Redis에 연결하지 못하고 있다는 의미입니다. 애플리케이션 에러로 이어지므로 즉시 조치가 필요합니다.

# PromQL - 커넥션 사용률
redis_connected_clients / redis_config_maxclients * 100

# 거부된 연결 발생률
rate(redis_rejected_connections_total[5m])

3. 처리량 (Throughput)

OPS(Operations Per Second)는 Redis의 처리량을 나타냅니다. Redis는 싱글 스레드로 동작하기 때문에 하나의 CPU 코어만 사용합니다. 일반적인 GET/SET 명령은 초당 10만~20만 OPS까지 처리 가능합니다.

OPS 추이 (1주간) - 콘텐츠 서비스 패턴

뉴스/미디어 서비스의 전형적인 OPS 패턴입니다. 출퇴근 시간과 점심시간에 피크가 발생하고, 심야에는 배치 작업으로 인한 스파이크가 관찰됩니다.

⚠️

화요일 새벽 3시 스파이크(35K): 정기 배치 작업(캐시 워밍)으로 인한 의도된 증가입니다. 배치 스케줄을 문서화하지 않으면 장애로 오인할 수 있습니다.

ℹ️

OPS가 높다고 무조건 좋은 것은 아닙니다. 명령별로 복잡도가 다르기 때문입니다.

명령별 복잡도:

  • GET, SET: O(1) - 빠름
  • KEYS *: O(N) - 키가 많으면 매우 느림, 프로덕션 금지
  • SMEMBERS: O(N) - 큰 Set에서는 느림
redis-cli INFO stats

주요 지표:

  • total_commands_processed: 처리된 총 명령 수
  • instantaneous_ops_per_sec: 초당 명령 처리 수 (OPS)
# PromQL - OPS (Operations Per Second)
rate(redis_commands_processed_total[5m])

# 명령별 OPS
rate(redis_commands_total{cmd="get"}[5m])
rate(redis_commands_total{cmd="set"}[5m])

4. 지연 시간 (Latency)

Redis를 사용하는 이유는 빠른 응답 속도입니다. 일반적으로 1ms 이하의 응답 시간을 기대합니다.

응답 시간 스파이크 (1주간) - RDB 스냅샷 영향

매일 새벽 4시 RDB 스냅샷 저장 시 발생하는 레이턴시 스파이크입니다. fork() 시스템 콜로 인해 순간적으로 지연이 발생합니다.

🚨

수요일 14시 비정상 스파이크(85ms): 개발자가 실수로 KEYS * 명령을 실행한 사례입니다. 프로덕션에서 이 명령은 반드시 비활성화하세요.

ℹ️

새벽 4시 정기 스파이크(24~32ms): RDB 스냅샷으로 인한 예상된 지연입니다. 트래픽이 적은 시간대에 스케줄링되어 있어 서비스 영향은 미미합니다.

지연 시간이 증가한다면:

  • 느린 명령 실행 (KEYS, SMEMBERS 등 O(N) 명령)
  • 메모리 부족으로 스왑 발생
  • 네트워크 지연
  • Persistence(RDB/AOF) 작업으로 인한 블로킹
💡

슬로우로그 설정을 프로덕션에서는 10ms가 아닌 1ms 정도로 낮춰서 설정하세요. 더 많은 느린 명령을 잡아낼 수 있습니다.

# 슬로우로그 확인
redis-cli SLOWLOG GET 10

# 지연 시간 측정 모드
redis-cli --latency
redis-cli --latency-history

알람 기준:

  • 평균 응답 시간 1ms 초과: 조사 필요
  • 슬로우로그 급증: 큰 키 또는 복잡한 명령 조사
# PromQL - 슬로우로그 카운트
redis_slowlog_length

# 명령별 지연 시간 (redis_exporter 설정 필요)
redis_commands_duration_seconds_total / redis_commands_total

5. 히트율 (Hit Ratio)

Redis를 캐시로 사용할 때 가장 중요한 지표입니다. 히트율이 낮다는 것은 캐시가 제 역할을 못한다는 의미입니다.

히트율 추이 (2주간) - 배포 영향 분석

신규 기능 배포 전후의 히트율 변화입니다. 배포 직후 캐시 미스가 증가하다가 점차 안정화되는 패턴을 보여줍니다.

🚨

2주차 월요일 급락(78.3%): 신규 기능 배포로 캐시 키 구조가 변경되었습니다. 캐시 워밍 없이 배포하면 DB에 순간적으로 큰 부하가 발생합니다.

💡

배포 시 캐시 전략: 키 구조 변경 시에는 (1) 블루-그린 캐시 키 버저닝 또는 (2) 사전 캐시 워밍 스크립트를 활용하세요.

히트율이 낮은 원인:

  • TTL이 너무 짧음: 데이터가 만료되기 전에 다시 요청되지 않음
  • 워킹 셋이 메모리보다 큼: 자주 사용되는 데이터가 eviction됨
  • 캐시 키 설계 문제: 같은 데이터인데 다른 키로 저장/조회
redis-cli INFO stats | grep keyspace

주요 지표:

  • keyspace_hits: 키를 찾은 횟수
  • keyspace_misses: 키를 못 찾은 횟수
  • Hit Ratio = hits / (hits + misses) × 100
# PromQL - 히트율
redis_keyspace_hits_total /
(redis_keyspace_hits_total + redis_keyspace_misses_total) * 100

6. 키 관리 (Keys)

evicted_keys메모리 부족의 명확한 신호입니다. maxmemory에 도달하면 설정된 정책(maxmemory-policy)에 따라 키가 강제로 삭제됩니다.

Eviction 발생 (2주간) - 프로모션 이벤트 영향

블랙프라이데이 세일 기간 중 발생한 eviction입니다. 평소에는 0이던 eviction이 이벤트 기간 동안 급증했습니다.

🚨

2주차 금요일 피크(2,340개/분): 블랙프라이데이 시작 시점입니다. 캐시 용량 산정 시 최대 트래픽의 1.5배 여유를 확보하지 않으면 이런 상황이 발생합니다.

💡

사후 조치: 이 사건 이후 maxmemory를 4GB → 6GB로 증설하고, 프로모션 전 캐시 프리워밍을 도입했습니다. 이후 동일 규모 이벤트에서 eviction 0을 달성했습니다.

🚨

evicted_keys가 증가하면 메모리가 부족하다는 의미입니다. 캐시 데이터가 강제로 삭제되어 히트율이 떨어지고, 원본 데이터 소스에 부하가 증가합니다.

주요 eviction 정책:

redis-cli INFO keyspace
redis-cli DBSIZE

주요 지표:

  • db0:keys: DB별 키 개수
  • expired_keys: 만료된 키 수
  • evicted_keys: maxmemory 정책으로 삭제된 키 수
# PromQL - 키 제거율
rate(redis_evicted_keys_total[5m])

# 키 만료율
rate(redis_expired_keys_total[5m])

7. 복제 (Replication)

redis-cli INFO replication

주요 지표:

  • role: master 또는 slave
  • connected_slaves: 연결된 Replica 수
  • master_link_status: Replica의 Master 연결 상태
  • master_last_io_seconds_ago: 마지막 Master 통신 이후 경과 시간
  • repl_backlog_size: 복제 백로그 크기
🚨

master_link_status가 “up”이 아니면 복제가 끊긴 상태입니다. Replica가 오래된 데이터를 서빙할 수 있으니 즉시 조치하세요.

알람 기준:

  • master_link_status != “up”: Critical
  • master_last_io_seconds_ago > 10: Warning
  • connected_slaves 감소: 조사 필요
# PromQL - 복제 지연
redis_master_last_io_seconds_ago

# Master 연결 상태 (1 = up, 0 = down)
redis_master_link_up

8. 영속성 (Persistence)

RDB/AOF 설정 시 모니터링이 필요합니다.

redis-cli INFO persistence

주요 지표:

  • rdb_last_bgsave_status: 마지막 RDB 저장 상태
  • rdb_last_bgsave_time_sec: 마지막 RDB 저장 소요 시간
  • aof_last_rewrite_time_sec: 마지막 AOF 재작성 소요 시간
  • aof_rewrite_in_progress: AOF 재작성 진행 중 여부

알람 기준:

  • rdb_last_bgsave_status != “ok”: Critical
  • bgsave 소요 시간 급증: 데이터 증가 또는 I/O 문제
# PromQL - RDB 저장 상태 (1 = ok)
redis_rdb_last_bgsave_status

# AOF 재작성 진행 중
redis_aof_rewrite_in_progress

9. AWS ElastiCache 전용 지표

AWS ElastiCache를 사용한다면 CloudWatch에서 추가 메트릭을 확인할 수 있습니다.

CPU 사용률: CPUUtilization vs EngineCPUUtilization

ElastiCache에는 두 가지 CPU 메트릭이 있습니다. EngineCPUUtilization이 Redis 엔진 자체의 CPU를 나타내므로 더 중요합니다.

⚠️

목요일 EngineCPU 72%: Redis는 싱글 스레드이므로 한 코어만 사용합니다. AWS는 EngineCPUUtilization을 90% 미만으로 유지할 것을 권장하며, 다단계 알람(예: 65% Warning, 90% Critical) 설정을 제안합니다. 다만 실제 임계값은 워크로드 특성에 따라 벤치마킹 후 결정해야 합니다. (AWS 공식 문서)

ℹ️

4 vCPU 이상 노드는 EngineCPUUtilization, 2 vCPU 이하 노드는 CPUUtilization을 주로 모니터링하세요. 두 메트릭을 함께 보는 것이 권장됩니다. (AWS Database Blog)

네트워크 I/O (1주간)

대용량 캐시 데이터를 다루는 경우 네트워크 대역폭이 병목이 될 수 있습니다.

ℹ️

BytesOut이 BytesIn보다 훨씬 높음: 캐시 히트 시 저장된 데이터를 반환하므로 정상적인 패턴입니다. 반대로 BytesIn이 높다면 쓰기 위주 워크로드입니다.

DB0 평균 TTL (1주간)

TTL 분포를 모니터링하면 캐시 전략의 효율성을 파악할 수 있습니다.

⚠️

TTL 감소 추세: 평균 TTL이 점점 낮아지고 있습니다. TTL이 너무 짧으면 캐시 효율이 떨어지고 DB 부하가 증가합니다. 데이터 특성에 맞는 TTL 전략 검토가 필요합니다.

스왑 사용량 모니터링

🚨

Redis에서 스왑이 발생하면 성능이 극적으로 저하됩니다. SwapUsage는 항상 0이어야 합니다.

# CloudWatch 메트릭
aws cloudwatch get-metric-statistics \
  --namespace AWS/ElastiCache \
  --metric-name SwapUsage \
  --dimensions Name=CacheClusterId,Value=my-redis-cluster \
  --start-time 2024-01-01T00:00:00Z \
  --end-time 2024-01-07T00:00:00Z \
  --period 3600 \
  --statistics Average

ElastiCache 주요 CloudWatch 메트릭:

메트릭설명알람 기준
EngineCPUUtilizationRedis 엔진 CPU 사용률 (4+ vCPU 노드)> 90% Critical (AWS 권장), Warning은 워크로드에 따라
DatabaseMemoryUsagePercentage데이터가 사용하는 메모리 비율> 80% Warning, > 90% Critical
SwapUsage스왑 메모리 사용량> 0 Critical
CacheHitRate캐시 히트율< 90% Warning
ReplicationLag복제 지연 (초)> 1초 Warning
NetworkBytesIn/Out네트워크 I/O인스턴스 한도의 80%
DB0AverageTTLDB0의 평균 TTL비즈니스 요구사항에 따라

부하 상황에서의 모니터링

읽기 부하 (Read-Heavy)

관찰 포인트:

  • OPS 증가
  • 커넥션 수 증가
  • 네트워크 대역폭 사용량
# 핫키 확인 (Redis 4.0+)
redis-cli --hotkeys

# 메모리 사용량 큰 키 확인
redis-cli --bigkeys

쓰기 부하 (Write-Heavy)

관찰 포인트:

  • 메모리 사용량 급증
  • AOF fsync 지연
  • 복제 지연 증가
# 쓰기 부하 확인
redis-cli INFO stats | grep -E "total_writes|sync"

메모리 부족 상황

관찰 포인트:

  • evicted_keys 급증
  • used_memorymaxmemory에 근접
  • OOM 에러 발생
# 메모리 분석
redis-cli MEMORY DOCTOR
redis-cli MEMORY STATS

대용량 데이터 작업 모니터링

KEYS 명령 대신 SCAN 사용

# 프로덕션에서 절대 금지!
redis-cli KEYS "user:*"

KEYS 명령의 위험성:

  • O(N) 복잡도로 전체 키 스캔
  • 싱글 스레드 Redis를 블로킹
  • 다른 모든 요청이 대기

대용량 키 삭제

# 큰 키 삭제 시 블록킹 발생
redis-cli DEL huge_set

모니터링 포인트:

# 명령별 실행 횟수
rate(redis_commands_total{cmd="keys"}[5m])  # 0이어야 함
rate(redis_commands_total{cmd="scan"}[5m])

대량 데이터 로딩

# 파이프라인 사용
cat commands.txt | redis-cli --pipe

# MASS INSERT 모니터링
redis-cli INFO stats | grep -E "total_commands|instantaneous"

모니터링 포인트:

  • 메모리 사용량 증가 추이
  • RDB/AOF 지연
  • 복제 지연

Grafana 대시보드 구성

추천 패널 레이아웃

┌─────────────────────────────────────────────────────────┐
│  Overview: OPS, 메모리 사용률, 히트율, 커넥션           │
├─────────────────────────────────────────────────────────┤
│  Memory Usage         │  Memory Fragmentation          │
├───────────────────────┼────────────────────────────────┤
│  Commands per Second  │  Hit Rate                      │
├───────────────────────┼────────────────────────────────┤
│  Connections          │  Keys / Evicted Keys           │
├─────────────────────────────────────────────────────────┤
│  Replication Status   │  Persistence (RDB/AOF)         │
└─────────────────────────────────────────────────────────┘

커뮤니티 대시보드

💡

Grafana Labs에서 제공하는 커뮤니티 대시보드를 활용하면 빠르게 시작할 수 있습니다.

redis_exporter 설정

# docker-compose.yml
services:
  redis_exporter:
    image: oliver006/redis_exporter
    environment:
      REDIS_ADDR: "redis://redis:6379"
      REDIS_PASSWORD: ""
    ports:
      - "9121:9121"

알람 규칙 예시

성능 최적화 체크리스트

메모리 최적화

# 메모리 정책 확인
redis-cli CONFIG GET maxmemory-policy

# 추천 정책
# - 캐시용: allkeys-lru 또는 volatile-lru
# - 세션용: volatile-ttl

슬로우로그 설정

# 10ms 이상 걸린 명령 기록
redis-cli CONFIG SET slowlog-log-slower-than 10000
redis-cli CONFIG SET slowlog-max-len 128

위험한 명령 비활성화

⚠️

프로덕션 환경에서는 KEYS, FLUSHALL, FLUSHDB 같은 위험한 명령을 반드시 비활성화하세요. 실수로 실행하면 서비스 장애로 이어집니다.

# redis.conf
rename-command KEYS ""
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command DEBUG ""

정리

Redis 모니터링의 핵심 포인트:

  1. 메모리: 사용률과 단편화 비율 주시
  2. 히트율: 캐시 효율성 지표
  3. 키 제거: evicted_keys는 메모리 부족 신호
  4. 복제: master_link_up과 지연 시간 확인
  5. 슬로우로그: 성능 저하 원인 분석

다음 글에서는 JVM 모니터링에 대해 다룹니다.


참고 자료

© 2025, 미나리와 함께 만들었음