Theme:

Redis를 프로덕션에 배포한 후 성능이 갑자기 떨어지거나 장애가 발생하면 어떻게 원인을 찾아야 할까요?

Redis 운영이란

Redis를 단순히 "사용"하는 것과 "운영"하는 것은 다릅니다. 운영은 모니터링으로 현재 상태를 파악하고, 문제가 발생하기 전에 예방하며, 장애 시 빠르게 원인을 진단하고 대응하는 것입니다.

INFO — 모든 것의 시작

INFO 명령은 Redis 서버의 상태를 한눈에 보여주는 가장 중요한 명령입니다.

BASH
# 전체 정보
127.0.0.1:6379> INFO

# 섹션별 조회
127.0.0.1:6379> INFO memory
127.0.0.1:6379> INFO stats
127.0.0.1:6379> INFO replication
127.0.0.1:6379> INFO clients
127.0.0.1:6379> INFO keyspace

핵심 모니터링 지표

메모리

BASH
127.0.0.1:6379> INFO memory
used_memory:1073741824          # Redis가 사용 중인 메모리 (1GB)
used_memory_rss:1288490188      # OS가 Redis에 할당한 물리 메모리
used_memory_peak:2147483648     # 최대 메모리 사용량
mem_fragmentation_ratio:1.20    # RSS / used_memory (1.0~1.5 정상)
maxmemory:2147483648            # 설정된 최대 메모리
maxmemory_policy:allkeys-lru    # eviction 정책

주의해야 할 상황:

  • mem_fragmentation_ratio > 1.5: 메모리 단편화 심각
  • mem_fragmentation_ratio < 1.0: 스왑 사용 중 (매우 위험)
  • used_memorymaxmemory에 근접: eviction 발생 가능

클라이언트

BASH
127.0.0.1:6379> INFO clients
connected_clients:150            # 현재 연결된 클라이언트 수
blocked_clients:2                # BRPOP 등으로 블로킹된 클라이언트
tracking_clients:10              # CLIENT TRACKING 활성화된 클라이언트
maxclients:10000                 # 최대 허용 연결 수

통계

BASH
127.0.0.1:6379> INFO stats
total_commands_processed:1234567 # 총 처리 명령 수
instantaneous_ops_per_sec:15000  # 현재 초당 명령 처리 수
keyspace_hits:900000             # 캐시 히트 수
keyspace_misses:100000           # 캐시 미스 수
# 히트율: 900000 / (900000 + 100000) = 90%

evicted_keys:0                   # eviction된 키 수 (0이 이상적)
rejected_connections:0           # 거부된 연결 수

SLOWLOG — 느린 명령 추적

설정

BASH
# 실행 시간이 10000마이크로초(10ms) 이상인 명령 기록
CONFIG SET slowlog-log-slower-than 10000

# 최대 128개 기록 유지
CONFIG SET slowlog-max-len 128

# 모든 명령 기록 (디버깅용, 프로덕션 비권장)
CONFIG SET slowlog-log-slower-than 0

# 비활성화
CONFIG SET slowlog-log-slower-than -1

조회

BASH
# 최근 10개
127.0.0.1:6379> SLOWLOG GET 10
1) 1) (integer) 14            # 로그 ID
   2) (integer) 1679000000    # Unix 타임스탬프
   3) (integer) 15430         # 실행 시간 (마이크로초) = 15.4ms
   4) 1) "KEYS"               # 명령
      2) "*"                   # 인자
   5) "192.168.1.100:52140"   # 클라이언트 주소
   6) ""                       # 클라이언트 이름

# 로그 수 확인
127.0.0.1:6379> SLOWLOG LEN
(integer) 42

# 로그 초기화
127.0.0.1:6379> SLOWLOG RESET

자주 잡히는 느린 명령들

BASH
KEYS *                     # O(N) — 프로덕션에서 금지, SCAN 사용
SMEMBERS large-set          # O(N) — 큰 Set 전체 조회
SORT large-list            # O(N+M*log(M)) — 정렬
HGETALL large-hash         # O(N) — 큰 Hash 전체 조회
DEL large-key              # 큰 키는 UNLINK 사용
FLUSHDB / FLUSHALL         # ASYNC 옵션 사용

LATENCY — 내부 이벤트 지연 추적

활성화

BASH
# 1ms 이상 지연되는 이벤트 추적
CONFIG SET latency-tracking-info-percentiles "50 99 99.9"
CONFIG SET latency-monitor-threshold 1  # 밀리초

조회

BASH
# 최근 지연 이벤트
127.0.0.1:6379> LATENCY LATEST
1) 1) "fork"                  # 이벤트 이름
   2) (integer) 1679000000    # 마지막 발생 시간
   3) (integer) 150           # 마지막 지연 시간 (ms)
   4) (integer) 300           # 최대 지연 시간 (ms)

# 특정 이벤트의 이력
127.0.0.1:6379> LATENCY HISTORY fork
1) 1) (integer) 1679000000
   2) (integer) 150
2) 1) (integer) 1678999000
   2) (integer) 120

# 진단 도움
127.0.0.1:6379> LATENCY DOCTOR
"I have a few latency reports..."

주요 이벤트

  • fork: RDB 저장이나 AOF 리라이트를 위한 fork() 지연
  • aof-rewrite-diff-write: AOF 리라이트 중 diff 쓰기
  • expire-cycle: 만료 키 정리 사이클
  • eviction-cycle: 메모리 부족 시 eviction 사이클

redis-cli 진단 도구

--bigkeys

BASH
redis-cli --bigkeys
# 타입별 가장 큰 키 보고
# Biggest string found 'cache:homepage' has 524288 bytes
# Biggest hash found 'user:profiles' has 50000 fields
# Biggest list found 'queue:jobs' has 1000000 items

--memkeys (Redis 7.0+)

BASH
redis-cli --memkeys
# 메모리 사용량 기준으로 가장 큰 키 보고

--stat

BASH
redis-cli --stat
# 실시간 통계 (1초 간격)
------- data ------ --------------------- load ----- ...
keys       mem      clients blocked requests ...
150000     1.20G    50      0       (+15000) ...
150100     1.20G    50      0       (+14500) ...

--latency

BASH
# 레이턴시 측정
redis-cli --latency
min: 0, max: 1, avg: 0.19 (1000 samples)

# 히스토그램
redis-cli --latency-history -i 5
# 5초 간격으로 레이턴시 히스토그램 출력

# 분포도
redis-cli --latency-dist

메모리 단편화 관리

원인

  • 다양한 크기의 키를 반복적으로 생성/삭제
  • jemalloc의 메모리 할당 특성
  • 긴 시간 운영 후 누적

진단

BASH
127.0.0.1:6379> INFO memory
mem_fragmentation_ratio:2.5  # 2.5배 — 심각

# 상세 분석
127.0.0.1:6379> MEMORY DOCTOR

해결

BASH
# 1. Active Defragmentation (온라인)
CONFIG SET activedefrag yes
CONFIG SET active-defrag-ignore-bytes 100mb
CONFIG SET active-defrag-threshold-lower 10
CONFIG SET active-defrag-cycle-min 1
CONFIG SET active-defrag-cycle-max 25

# 2. 재시작 (오프라인 — 가장 확실)
# RDB/AOF로 백업 후 재시작하면 메모리가 깔끔하게 재할당됨

CONFIG 동적 변경

서버를 재시작하지 않고 설정을 변경할 수 있습니다.

BASH
# 현재 설정 조회
127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "2147483648"

# 설정 변경
127.0.0.1:6379> CONFIG SET maxmemory 4gb
OK

# 설정을 파일에 영구 저장
127.0.0.1:6379> CONFIG REWRITE
OK

자주 변경하는 설정

BASH
# 메모리 관련
CONFIG SET maxmemory 4gb
CONFIG SET maxmemory-policy allkeys-lru

# 성능 관련
CONFIG SET hz 100  # 이벤트 루프 주기 (기본 10, 높이면 만료/eviction이 더 자주)
CONFIG SET slowlog-log-slower-than 5000

# 영속성 관련
CONFIG SET save ""  # RDB 스냅샷 비활성화
CONFIG SET appendonly yes  # AOF 활성화

동적 변경 불가능한 설정

BASH
# 재시작 필요
io-threads        # I/O 스레드 수
port              # 포트 번호
bind              # 바인드 주소
cluster-enabled   # 클러스터 모드

장애 대응 체크리스트

레이턴시 급증 시

BASH
# 1. 슬로우 로그 확인
SLOWLOG GET 20

# 2. 클라이언트 수 확인
INFO clients

# 3. 메모리 확인 (eviction, 스왑)
INFO memory

# 4. 네트워크 확인
redis-cli --latency

# 5. 백그라운드 작업 확인 (fork 등)
LATENCY LATEST
INFO persistence  # rdb_last_bgsave_status, aof_last_bgrewrite_status

메모리 부족 시

BASH
# 1. 현재 메모리 상태
INFO memory

# 2. 큰 키 찾기
redis-cli --bigkeys

# 3. 만료되지 않은 불필요한 키 확인
# SCAN으로 TTL 없는 키 찾기
redis-cli --scan --pattern "temp:*"

# 4. maxmemory-policy 확인
CONFIG GET maxmemory-policy

# 5. 긴급: maxmemory 상향 또는 불필요한 키 삭제
CONFIG SET maxmemory 8gb

연결 폭주 시

BASH
# 1. 현재 연결 수
INFO clients

# 2. 연결별 상세 정보
CLIENT LIST

# 3. 유휴 연결 정리
CONFIG SET timeout 300  # 5분 유휴 시 연결 끊기

# 4. 느린 클라이언트 확인
CLIENT LIST TYPE normal
# age, idle, cmd 등으로 문제 클라이언트 식별

모니터링 시스템 구축

BASH
# Prometheus + Redis Exporter 조합 권장
# 주요 메트릭:
# - redis_connected_clients
# - redis_used_memory_bytes
# - redis_memory_fragmentation_ratio
# - redis_commands_processed_total
# - redis_keyspace_hits_total / redis_keyspace_misses_total
# - redis_evicted_keys_total
# - redis_slowlog_length

알림 기준 예시

PLAINTEXT
경고 (Warning):
- mem_fragmentation_ratio > 1.5
- connected_clients > maxclients * 0.8
- used_memory > maxmemory * 0.9
- evicted_keys 증가

긴급 (Critical):
- mem_fragmentation_ratio < 1.0 (스왑 사용)
- connected_clients = maxclients
- used_memory >= maxmemory
- master_link_status:down (복제 끊김)

정리

  • INFO는 Redis 상태 파악의 출발점입니다. memory, stats, clients 섹션을 주기적으로 확인하세요
  • SLOWLOG로 느린 명령을 찾고, O(N) 명령을 제거하거나 최적화하세요
  • LATENCY로 내부 이벤트(fork, eviction)의 지연을 추적하세요
  • 메모리 단편화는 activedefrag로 온라인 해결하거나, 심각하면 재시작하세요
  • CONFIG SET으로 대부분의 설정을 재시작 없이 변경할 수 있습니다
  • Prometheus + Grafana 조합으로 체계적인 모니터링 시스템을 구축하는 것이 중요합니다
댓글 로딩 중...