Notice
Recent Posts
Recent Comments
Link
«   2026/06   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

ssuperjun 님의 블로그

[장애 이력 자동 작성 도구8] Redis Too many connections(maxclients 초과) 장애 상황 연출 및 deprecated 이유 & CPU 병목 스킵 이유 본문

인턴

[장애 이력 자동 작성 도구8] Redis Too many connections(maxclients 초과) 장애 상황 연출 및 deprecated 이유 & CPU 병목 스킵 이유

ssuperjun 2026. 3. 10. 13:40

현재 구현 상황

항목 상태
OOM Kill 수집/타임라인/두레이 등록 완료
디스크 full 스킵
CPU 병목 스킵
Too many connections 🔲 미시작
Segfault 🔲 미시작
Sentinel 구조 🔲 미시작
마스터-슬레이브 복제 구조 🔲 미시작

 

CPU 병목 스킵 이유

  • keys *같은 O(N) 명령어를 대량 데이터에 실행하면 CPU 병목이 발생하는데, 대부분은 Redis의 응답 지연만 발생하고 프로세스는 그대로 살아있어 장애라고 보기 어려울 수 있음
  • CPU 병목으로 인해 Redis를 죽이는 장애 상황은 연출하기 힘듦
  • keys *같은 명령어가 CPU 병목의 원인이 됐다는 사실은 journalctl(systemd 레벨)에 기록되지 않고, Redis 내부에서 Redis가 살아있을 때만 접근 가능하기 때문에 Redis가 재시작되면 기록은 메모리에서 사라짐
  • 장애가 발생한 직후 1차적인 정보 수집 부분은 추후 '고도화' 시 구현하기로 했으므로 스킵(장애 발생 직후 1차적으로 스크립트를 실행(원인 분석 및 휘발성 상태 정보 보존 목적) -> 1차 실행 때 수집한 정보를 사후 2차 실행에서 재활용)

참고

Redis 내부에서만 확인 가능한 정보

  • SLOWLOG — 실행 시간이 임계값(기본 10ms) 초과한 명령어 기록
  • LATENCY — 이벤트별 지연 시간 기록
  • INFO stats — rejected_connections, blocked_clients 등
  • INFO commandstats — 명령어별 실행 횟수/누적 시간

배경지식

Too many connections 기록이 저장되는 위치

  • INFO stats의 rejected_connections → 휘발성 (재시작 시 초기화)
  • Redis 로그 파일(/var/log/redis/redis-server.log) → 영구 기록

Redis도 MySQL처럼 Too many connections 문제가 발생하지만, 메커니즘이 다름

  • Redis는 maxclients 설정(기본값 10000)을 초과하면 새 연결을 거부하면서 로그에 기록
  • 하지만 Redis 단일 스레드이기에 10000 연결 차기 직전에 응답 지연이 심해지는 경우가 많음

구현 시작

 

1. 디스크 full 장애 연출 이전 상태로 되돌리기

 

#새 터미널에서 현재 redis-server pid 확인

sudo systemctl status redis-server | grep "Main PID"

 

# RDB 저장 없이 즉시 종료 명령

redis-cli -p 6379 config set save ""
redis-cli -p 6379 shutdown nosave

sudo systemctl restart redis-server
sudo lsof /mnt/redis-test  # 아무것도 안 나와야 함
sudo umount /mnt/redis-test
df -h | grep redis-test  # 마운트 해제 확인

 


2. 현재 환경 파악

 

2-1. redis-server(7.0버전) 기준

# maxclients 설정 확인
redis-cli -p 6379 config get maxclients

# 현재 연결 수 확인
redis-cli -p 6379 info clients | grep connected_clients

# Redis 로그 파일 위치 확인 (로그 수집 대상)
sudo cat /etc/redis/redis.conf | grep "^logfile"

 

결과

irteamsu@infa-testsrv-cb801:~$ redis-cli -p 6379 config get maxclients
1) "maxclients"
2) "10000"

irteamsu@infa-testsrv-cb801:~$ redis-cli -p 6379 info clients | grep connected_clients
connected_clients:1

irteamsu@infa-testsrv-cb801:~$ sudo cat /etc/redis/redis.conf | grep "^logfile"
logfile /var/log/redis/redis-server.log

 

2-2. Valkey 기준

사내 Redis 버전은 7.2 이상의 Valkey이기에, Valkey 기준으로 장애 연출 진행

 

참고

회사에서 Valkey를 사용하는 이유: 원래 Redis는 오픈소스였지만 2024년 3월 이후 상업 라이선스로 전환했기에, 마지막 오픈소스 버전인 7.2를 fork해서 만든 Valkey를 사용해 오픈소스를 유지하기 위함

 

#비밀번호와 renamed 명령어 확인

=> config 명령어가 redisconfig 변경돼 있어서 config get 안됨, info로 확인  requirepass 또는 ACL 설정 때문에 info 명령어가 막힘

grep -E "^requirepass|^masterauth" /home1/irteam/valkey_10379/valkey_10379.conf

 

#maxclients 설정 확인(info 확인)

/home1/irteam/valkey_10379/bin/redis-cli -p 10379 -a 비밀번호 info clients

 

#현재 연결 확인

/home1/irteam/valkey_10379/bin/redis-cli -p 10379 -a 비밀번호 redisconfig get maxclients

 

결과

현재 연결 수: 1 (정상)

maxclients: 10000 (기본값)

 

# Valkey 설정 파일 위치 확인

find /home1/irteam/valkey_10379 -name "*.conf" 2>/dev/null

메인 설정 파일 경로: /home1/irteam/valkey_10379/valkey_10379.conf

 

# 로그 파일 절대 경로 확인

find /home1/irteam/valkey_10379 -name "valkey_10379.log" 2>/dev/null

로그 파일 경로: /home1/irteam/valkey_10379/valkey_10379.log


3. 장애 연출

 

계획

  • maxclients를 낮게 설정(예: 5)한 뒤 연결을 폭주시키기
  • 런타임으로 설정 파일 수정 및 재시작 없이 진행

3-1. maxclients를 5로 낮춤

/home1/irteam/valkey_10379/bin/redis-cli -p 10379 -a 비밀번호 redisconfig set maxclients 5

 

# 확인

/home1/irteam/valkey_10379/bin/redis-cli -p 10379 -a 비밀번호 redisconfig get maxclients

 

3-2. 연결 폭주시키기

시도1 -> 실패

# 10개 연결을 동시에 시도 (5개 초과 → 거부 발생)
for i in $(seq 1 10); do
    /home1/irteam/valkey_10379/bin/redis-cli -p 10379 -a aASYerfXXOiArYanjCB9QmgYk9yHiP ping &
done
wait

# 로그 확인
tail -20 /home1/irteam/valkey_10379/valkey_10379.log

 

시도2

# 연결을 유지한 채로 10개 동시 접속
for i in $(seq 1 10); do
    /home1/irteam/valkey_10379/bin/redis-cli -p 10379 -a 비밀번호 subscribe dummy_channel &
done

# 잠시 대기 후 로그 확인
sleep 3
tail -20 /home1/irteam/valkey_10379/valkey_10379.log

# 백그라운드 프로세스 정리
kill $(jobs -p) 2>/dev/null (멈춘 터미널 ctrl+c 후 실행)
(kill %1 %2 %3 %4 %5 %6 %7 %8 %9 %10 2>/dev/null)

 

결과

AUTH failed: ERR max number of clients reached

=> 장애 연출에는 성공했지만, 로그 파일에는 아무것도 찍히지 않음


원인 분석

Too many connections 거부 메시지를 로그 파일이 아닌 클라이언트에게만 반환하고 있는 것인지 확인

# loglevel 확인

grep -E "^loglevel" /home1/irteam/valkey_10379/valkey_10379.conf

 

결과

loglevel notice

 

결과 분석 4줄 요약

  • Too many connections 거부는 verbose 레벨(자세히 출력)로 기록되기 때문에 notice 레벨에서는 로그 파일에 찍히지 않음
  • loglevel을 verbose로 변경해야 Too many connections 문제를 로그에서 확인할 수 있지만, 실제 운영 환경에서는 loglevel을 verbose로 운영하지 않을 가능성이 높음
  • Too many connections를 감지하고 싶다면 로그 파일 대신 INFO stats의 rejected_connections 카운터로 감지하는 것이 일반적임
  • 하지만, INFO stats는 Redis 내부에서 Redis가 살아있을 때만 접근 가능하기 때문에 Redis가 재시작되면 기록은 메모리에서 사라짐

 

결론

  • Too many connections 부분 구현도 스킵하자
  • 고도화(장애 발생 직후 1차적으로 스크립트를 실행(원인 분석 및 휘발성 상태 정보 보존 목적) -> 1차 실행 때 수집한 정보를 사후 2차 실행에서 재활용) 시 구현 예정