Redis의 모니터링 방법과 자주 발생하는 문제의 해결 방법을 정리합니다.

모니터링

INFO 명령어

INFO                    # 전체 정보
INFO server             # 서버 정보
INFO clients            # 클라이언트 정보
INFO memory             # 메모리 정보
INFO stats              # 통계
INFO replication        # 복제 상태
INFO keyspace           # DB별 키 수
INFO commandstats       # 명령어별 통계

핵심 모니터링 지표

지표 확인 명령 정상 범위
메모리 사용량 INFO memory → used_memory maxmemory의 80% 이하
메모리 단편화 mem_fragmentation_ratio 1.0 ~ 1.5
연결된 클라이언트 INFO clients → connected_clients maxclients 이하
초당 명령 수 INFO stats → instantaneous_ops_per_sec 환경에 따라
캐시 히트율 keyspace_hits / (hits + misses) 90% 이상
Eviction 수 evicted_keys 0에 가까울수록 좋음
블로킹 클라이언트 blocked_clients 0에 가까울수록 좋음
복제 지연 master_repl_offset 차이 0에 가까울수록 좋음

실시간 모니터링

# 실시간 명령 모니터링 (디버깅용, 운영 주의)
MONITOR

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

# 실시간 통계 (1초 간격)
redis-cli --stat

# 대용량 키 스캔
redis-cli --bigkeys

# 메모리 분석
redis-cli --memkeys

슬로우 로그

# 슬로우 로그 조회
SLOWLOG GET 10

# 출력 예시:
# 1) (integer) 14           ← 로그 ID
# 2) (integer) 1714900000   ← Unix timestamp
# 3) (integer) 15000        ← 실행 시간 (마이크로초)
# 4) 1) "KEYS"             ← 명령어
#    2) "*"

# 슬로우 로그 설정
CONFIG SET slowlog-log-slower-than 10000    # 10ms 이상
CONFIG SET slowlog-max-len 256

자주 발생하는 문제

1. OOM (Out of Memory)

OOM command not allowed when used memory > 'maxmemory'
원인 해결
maxmemory 초과 maxmemory 증가 또는 Eviction 정책 설정
TTL 미설정 캐시 키에 TTL 추가
대용량 키 키 분할 또는 불필요한 데이터 삭제
메모리 누수 --bigkeys로 대용량 키 확인
# 대용량 키 찾기
redis-cli --bigkeys

# 메모리 사용량 상위 키
MEMORY USAGE large_key

# Eviction 정책 설정
CONFIG SET maxmemory-policy allkeys-lru

2. 높은 지연 시간 (Latency)

원인 해결
느린 명령어 (KEYS, SMEMBERS 등) SCAN 사용, 대용량 컬렉션 분할
RDB/AOF fork 메모리 여유 확보, 빈도 조정
네트워크 문제 로컬 접속 확인, 네트워크 진단
스왑 사용 스왑 비활성화, 메모리 확보
대용량 키 삭제 UNLINK (비동기 삭제) 사용
# 지연 원인 분석
redis-cli --latency
redis-cli --intrinsic-latency 10    # 시스템 기본 지연 측정

# 느린 명령어 확인
SLOWLOG GET 20

# 스왑 사용 확인 (Linux)
# cat /proc/$(pidof redis-server)/smaps | grep Swap

3. 연결 거부 (maxclients 초과)

ERR max number of clients reached
# 현재 연결 수 확인
INFO clients
# connected_clients: 10001

# 최대 연결 수 확인/변경
CONFIG GET maxclients
CONFIG SET maxclients 20000

# 유휴 연결 타임아웃 설정
CONFIG SET timeout 300    # 5분 유휴 시 자동 종료

# 연결된 클라이언트 목록
CLIENT LIST
CLIENT KILL ID 12345      # 특정 클라이언트 종료

4. KEYS 명령어로 인한 블로킹

KEYS * 명령은 모든 키를 스캔하므로 운영 환경에서 서버를 블로킹합니다.

# ❌ 운영 환경 금지
KEYS user:*

# ✅ SCAN 사용 (커서 기반, 비블로킹)
SCAN 0 MATCH user:* COUNT 100
# 반환된 커서가 0이 될 때까지 반복

5. 메모리 단편화

INFO memory
# mem_fragmentation_ratio: 2.5  ← 비정상 (1.5 이상)
원인 해결
잦은 키 생성/삭제 activedefrag yes 활성화 (Redis 4.0+)
다양한 크기의 값 값 크기 통일 시도
오래 실행된 인스턴스 재시작 (RDB 로드)
# redis.conf - 자동 단편화 해소
activedefrag yes
active-defrag-ignore-bytes 100mb
active-defrag-threshold-lower 10
active-defrag-threshold-upper 100

6. 복제 지연 / 연결 끊김

# Master에서 확인
INFO replication
# slave0:...,lag=5  ← 5초 지연

# 원인 확인
# - Replica 네트워크 대역폭 부족
# - Replica 디스크 I/O 느림
# - 대량 쓰기로 인한 버퍼 초과
# redis.conf - 복제 버퍼 크기 증가
repl-backlog-size 256mb
client-output-buffer-limit replica 512mb 256mb 60

7. Thundering Herd (캐시 스탬피드)

인기 캐시 키가 만료되는 순간 수많은 요청이 동시에 DB를 조회하는 문제입니다.

해결 방법 설명
락 기반 갱신 한 요청만 DB 조회, 나머지는 대기
TTL 분산 만료 시간에 랜덤 값 추가
사전 갱신 TTL 만료 전에 백그라운드에서 갱신
# 락 기반 캐시 갱신
def get_with_lock(key):
    value = redis.get(key)
    if value:
        return value

    lock_key = f"lock:{key}"
    if redis.set(lock_key, "1", nx=True, ex=5):
        # 락 획득 성공 → DB 조회 후 캐시 저장
        value = db.query(...)
        redis.setex(key, 300, value)
        redis.delete(lock_key)
        return value
    else:
        # 락 획득 실패 → 잠시 대기 후 재시도
        time.sleep(0.1)
        return get_with_lock(key)

운영 체크리스트

항목 확인 방법 권장
maxmemory 설정 CONFIG GET maxmemory 물리 메모리의 70~80%
Eviction 정책 CONFIG GET maxmemory-policy 용도에 맞게 설정
영속성 설정 CONFIG GET save, CONFIG GET appendonly 용도에 맞게
슬로우 로그 SLOWLOG GET 정기 확인
대용량 키 redis-cli --bigkeys 정기 스캔
메모리 단편화 INFO memory ratio < 1.5
연결 수 INFO clients maxclients 대비 여유
복제 상태 INFO replication lag = 0
KEYS 명령 사용 금지 rename-command KEYS "" 운영 환경 필수
비밀번호 설정 requirepass 또는 ACL 필수

관련된 글 (redis > lecture-redis)