ssuperjun 님의 블로그
[장애 이력 자동 작성 도구12] Redis 스크립트 추가 고도화 본문
1. Failed with result 의 다른 요인
현재 상황
싱글 구성에서 "Failed with result" 키워드는 감지되는데, 'oom-kill', 'core-dump', 'signal' 외의 다른 요인으로 인해 "Failed with result"가 로그에 나타나는 상황은 전부 '미확인'처리 했음
하지만 systemd의 Failed with result 뒤에 올 수 있는 값은 여러가지임
| 값 | 의미 |
| oom-kill | OOM Killer가 프로세스 종료 |
| core-dump | Segfault 등으로 코어 덤프 발생 |
| signal | 외부 시그널로 종료 (SIGTERM 제외) |
| exit-code | 프로세스가 비정상 종료 코드로 종료 |
| timeout | systemd의 TimeoutStartSec/TimeoutStopSec 초과 |
| watchdog | systemd watchdog 응답 없음 |
| resources | cgroup 리소스 제한 초과 |
Redis에서 현실적으로 발생 가능한 것은 exit-code(설정 오류로 시작 실패)와 timeout(종료 시간 초과) 정도임
구분하는 것이 좋다고 판단해, 현재 미확인 (로그 수동 확인 필요)으로 처리되는 두 케이스를 아래처럼 세분화함
| 상황 | 현재 | 개선안 |
| Failed with result 'exit-code' 등 감지 | 미확인 | 비정상 종료 (exit-code) 등 result 값 그대로 출력 |
| Failed with result 자체가 없음 | 미확인 | 원인 미확인 (Failed with result 없음) |
구현 방식: Failed with result '(\S+)' 패턴으로 값을 추출해서 그대로 원인에 포함시키기
=> 구현 완료
| 원인 | 감지 키워드 | 태그 |
| OOM Kill | Failed with result 'oom-kill' | [OOM_KILL] |
| Segfault | Failed with result 'core-dump' | [SEGFAULT] |
| Signal Kill | Failed with result 'signal' | [KILL_SIGNAL] |
| 비정상 종료 - {result값} (원인 수동 확인 필요) | Failed with result 'exit_code 또는 timeout 등' | [FAILED_EXIT_CODE], [FAILED_TIMEOUT] |
| 미확인 (로그 수동 확인 필요) | Failed with result 자체가 없는 경우 |
valkey는 직접 실행되는 경우라 journalctl에 기록되지 않고 valkey 로그 파일에만 기록되는데, 만약 valkey를 systemd에 등록하면 systemd에 기록되는 로그의 형태가 Redis 7.0버전이든 7.2버전(Valkey)이든 동일한 형태로 로그에 기록되나?
=> 확인 필요
Valkey를 systemd에 등록하기
현재 Valkey 실행 방식 확인
# 현재 valkey 프로세스 확인
ps aux | grep valkey
# 기존 실행 스크립트/설정 위치 확인
ls /home1/irteam/valkey_10379/
systemd unit 파일 작성
sudo tee /etc/systemd/system/valkey-10379.service << 'EOF'
[Unit]
Description=Valkey 10379
After=network.target
[Service]
Type=forking
User=irteam
Group=irteam
ExecStart=/home1/irteam/valkey_10379/bin/redis-server /home1/irteam/valkey_10379/valkey_10379.conf
ExecStop=/home1/irteam/valkey_10379/bin/valkey-cli -p 10379 -a $(grep requirepass /home1/irteam/valkey_10379/valkey_10379.conf | awk '{print $2}') SHUTDOWN
PIDFile=/home1/irteam/valkey_10379/valkey_10379.pid
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
grep daemonize /home1/irteam/valkey_10379/valkey_10379.conf
# daemonize yes가 있어야 Type=forking이 정상 동작함. 없으면 추가하기.
echo "daemonize yes" >> /home1/irteam/valkey_10379/valkey_10379.conf
systemd 등록 및 시작
/home1/irteam/valkey_10379/bin/valkey-cli -p 10379 -a 비밀번호 REDISSHUTDOWN NOSAVE
sudo systemctl daemon-reload
sudo systemctl enable valkey-10379
sudo systemctl start valkey-10379
sudo systemctl status valkey-10379
Valkey 로그 확인
sudo journalctl -u valkey-10379 --no-pager -n 20

valkey의 journalctl 로그는 redis-server(7.0버전)과 동일한 형태인가?
다른 점
1: 프로세스 이름
Redis 7.0은 redis-server[pid]로 찍히지만, Valkey는 valkey[pid]로 찍힘
=> config에서 service명만 알맞게 수정해주면 문제 없음
2: Started 메시지 형태
Redis 7.0: "Started redis-server.service - Advanced key-value store"
Valkey: "Started valkey-10379.service - Valkey 10379"
다른 이벤트의 로그 패턴도 확인해보기
=> Valkey에 대해 OOM 장애 상황 연출
1. 메모리 제한 설정 (irteamsu)
# systemd MemoryLimit 설정
sudo systemctl edit valkey-10379
아래 내용 입력 후 저장:
[Service]
MemoryLimit=100M
sudo systemctl daemon-reload
sudo systemctl restart valkey-10379
# 확인
sudo systemctl show valkey-10379.service | grep MemoryLimit
2. Swap 비활성화 확인 (irteamsu)
free -h
sudo swapoff -a
free -h # Swap이 0인지 확인
3. RDB 비활성화 및 데이터 초기화 (irteam)
/home1/irteam/valkey_10379/bin/valkey-cli -p 10379 -a aASYerfXXOiArYanjCB9QmgYk9yHiP redisconfig set save ""
/home1/irteam/valkey_10379/bin/valkey-cli -p 10379 -a aASYerfXXOiArYanjCB9QmgYk9yHiP redisflushall
4. venv 생성 및 메모리 폭탄 스크립트 준비 (irteam)
python3 -m venv ~/venv-bomb
source ~/venv-bomb/bin/activate
pip install redis
# ~/bomb.py
import redis
import random
import string
r = redis.Redis(host='10.150.254.155', port=10379, password='aASYerfXXOiArYanjCB9QmgYk9yHiP')
def random_str(n):
return ''.join(random.choices(string.ascii_letters, k=n))
i = 0
while True:
r.set(random_str(20), random_str(1000))
i += 1
if i % 1000 == 0:
print(f"{i} keys inserted")
5. 메모리 폭탄 실행
python3 ~/bomb.py
6. Valkey 살아있는지 확인 (별도 터미널, irteam)
watch -n1 /home1/irteam/valkey_10379/bin/valkey-cli -p 10379 -a aASYerfXXOiArYanjCB9QmgYk9yHiP PING
7. 로그 확인 (별도 터미널, irteamsu)
# valkey 로그 파일
sudo tail -f /home1/irteam/valkey_10379/valkey_10379.log
# journalctl
sudo journalctl -u valkey-10379 -f


Valkey 로그 패턴 결과 정리
journalctl 기반 태그 (systemd 메시지)
systemd가 생성하는 메시지이므로 Redis/Valkey 무관하게 동일합니다.
| 태그 | 감지 키워드 | 판단 |
| [OOM_KILL] | Failed with result 'oom-kill' | ✓ 동일 |
| [SEGFAULT] | Failed with result 'core-dump' | ✓ 동일 |
| [KILL_SIGNAL] | Failed with result 'signal' | ✓ 동일 |
| [FAILED_{result}] | Failed with result '{기타값}' | ✓ 동일 |
| [RESTART] | Scheduled restart job, restart counter is at | ✓ 동일 |
| [RESTART_THROTTLE] | Start request repeated too quickly | ✓ 동일 |
| [STARTED] | Started redis-server / Started Advanced | ✗ 불일치 → Valkey: Started valkey-{port} |
| [STOPPING] | Stopping redis-server / Stopping Advanced | ✗ 불일치 가능 (미확인) |
| [STOPPED] | Stopped redis-server / Stopped Advanced | ✗ 불일치 가능 (미확인) |
redis 로그 파일 기반 태그 - 마스터 측
| 태그 | Redis 7.0 감지 키워드 | Valkey 8.1 감지 키워드 | 판단 |
| [REPLICA_CONN] | Synchronization with replica .* succeeded | Synchronization with replica .* succeeded | ✓ 동일 |
redis 로그 파일 기반 태그 - 슬레이브 측
| 태그 | Redis 7.0 감지 키워드 | Valkey 8.1 감지 키워드 | 판단 |
| [CONN_LOST] | Connection with master lost | Connection with primary lost | ✗ 불일치 |
| [FULL_RESYNC] | Full resync from master | Full resync from primary | ✗ 불일치 |
| [SYNC_FAIL] | I/O error trying to sync with MASTER | 미확인 | 확인 필요 |
| [SYNC_OK] | MASTER <-> REPLICA sync: Finished with success | PRIMARY <-> REPLICA sync: Finished with success | ✗ 불일치 |
| [PSYNC_OK] | Successful partial resynchronization with master | Successful partial resynchronization (master 없음) | ✓ 거의 동일 |
[SYNC_FAIL]은 이번 로그에서 발생하지 않아 미확인 상태입니다. Redis 7.0에서의 키워드는 I/O error trying to sync with MASTER인데, Valkey에서는 I/O error trying to sync with PRIMARY일 가능성이 높습니다. 한 번 확인이 필요합니다.
Sentinel 태그
Sentinel은 Redis/Valkey 버전과 무관하게 Sentinel 프로세스 자체의 로그 형식을 따르며, Valkey도 동일한 Sentinel 로그 형식을 사용합니다.
| 태그 | 감지 키워드 | 판단 |
| [SDOWN] | +sdown | ✓ 동일 |
| [SDOWN_RECOVER] | -sdown | ✓ 동일 |
| [ODOWN] | +odown | ✓ 동일 |
| [ODOWN_RECOVER] | -odown | ✓ 동일 |
| [FAILOVER] | +switch-master | ✓ 동일 |
| [FAILOVER_ABORT] | -failover-abort-* | ✓ 동일 |
| [REBOOT] | +reboot | ✓ 동일 |
| [NEW_EPOCH] | +new-epoch | ✓ 동일 |
| [CONFIG_UPDATE] | +config-update-from | ✓ 동일 |
코드 변경사항 요약
collect_journal_events — started/stopping/stopped 패턴
하드코딩된 redis-server / Advanced 대신 REDIS_SERVICE 변수를 직접 참조하도록 변경
conf의 service 항목이 valkey-10379이면 Started valkey-10379를 감지하고, redis-server이면 기존과 동일하게 동작
REPL_LOG_TAG_MAP — Valkey 키워드 추가
master → primary로 용어가 바뀐 Valkey 8.x의 슬레이브 로그 패턴 4개를 추가함
[SYNC_FAIL](I/O error trying to sync with PRIMARY)은 로그에서 직접 확인하지 못했지만 동일한 패턴으로 추가함
[REPLICA_CONN], [PSYNC_TRY], [PSYNC_OK] 부분은 동일한 패턴이므로 변경 없음
Stopping Advanced / Stopped Advanced는 그대로 유지
sudo systemctl stop valkey-10379
sudo journalctl -u valkey-10379 --no-pager -n 10
같은 명령어로 Stopping / Stopped 메시지가 어떤 형태로 찍히는지 확인 필요
실행 결과 로그 패턴: "Stopped valkey-10379.service - Valkey 10379"
=> 현재 코드의 파싱 로직으로 커버할 수 있음
'인턴' 카테고리의 다른 글
| [장애 이력 자동 작성 도구 14] MySQL 장애 연출 (0) | 2026.03.12 |
|---|---|
| [장애 이력 자동 작성 도구 13] MySQL 최종 정리 (0) | 2026.03.12 |
| [장애 이력 자동 작성 도구11] Redis 복제 구조 장애 상황 연출 및 로그 수집 코드 구현 (0) | 2026.03.10 |
| [장애 이력 자동 작성 도구10] Redis Sentinel 구조 장애 로그 수집 코드 구현 (0) | 2026.03.10 |
| [장애 이력 자동 작성 도구9] Redis Segfault 장애 상황 연출 및 로그 수집 코드 구현 (0) | 2026.03.10 |