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 님의 블로그

[장애 이력 자동 작성 도구2] 2차 정리 본문

인턴

[장애 이력 자동 작성 도구2] 2차 정리

ssuperjun 2026. 2. 26. 18:07

프로젝트 핵심

DB서버의 장애 이력을 시간 순서대로 기록

 

context

담당자가 장애 알림을 받으면, 원활한 서비스를 위해 서비스 정상화를 원인 파악보다 먼저 진행할 수 있으므로

추후 상황 보고 시 장애 이력을 시간 순서대로 정리해 놓은 타임라인이 필요

 

파이프라인 흐름 추상화

alert 받고 담당자가 스크립트 실행 -> 장애 이력 타임라인 작성(발생부터 완료까지의 일)

 

[구체화]

1. 담당자가 alert 인지

2. 담당자가 스크립트 실행(input = 장애가 발생한 서버 hostname)

3. 해당되는 DB 서버에서 로그 수집

4. 분석 및 임시 기록(Output 작성 중)

5. Output(두레이 태스크)

 

[1차 정리와 달라진 점]

스크립트를 장애 직후 원인 파악 용도로 사용하지 않음 - 고도화 부분에 해당

알람 종류가 달라도 조사할 부분은 동일 - error 키워드를 포괄적으로 감지한 뒤 원인 규명 세분화

 

[참고]

Redis를 기준으로 프로젝트 완성 후 MySQL로도 프로젝트 완성 예정

복제 구성 필요(Redis는 Cluster 말고 싱글과 Sentinel만 구성)


알람 예시

1. 복제중단 사례 : [김성훈0] mpsm-realdb-t1006:13306 모바일포커_CRM Replication stop
2. MySQL 접속 실패 : [김성훈] tc0m-goblindb-p1912:13306 NHNCloud_csap2_goblin MySQL Not Reachable
3. Redis Port 다운 : [전연주] tc0d-lncloredn-p1901:10379 NHNCloud_LogNCrash_GOV_KR1(Redis) Redis Port is Down!

 

=> 알람만 보고는 원인 유추가 어려움

 

알람 중요도 구분

장애 알람의 critical 여부를 따지기(알람 시 바로 장애 상황인 것, 그렇지 않은 것 존재)

 

*이 3가지 알람이 뜨면 담당자는 '사후 보고용 타임라인 작성'이 필요하다고 판단 -> 스크립트를 실행해야 함

[Redis]

1. 직관적인 DOWN 증상(매우 중요): Redis down, 시스템 다운, Redis port 다운(접속 불가)

2. STOP 및 DOWN으로 이어지는 증상(중요): 디스크 error, reject된 커넥션, Missing Master, Cluster Flapping(클러스터 내의 특정 노드(서버)나 서비스가 정상과 비정상 상태를 아주 짧은 시간 동안 끊임없이 반복해서 오가는 현상)

3. 마스터-슬레이브 간 문제: 복제 중단

 

*이 2가지 알람이 뜨면 담당자가 직접 판단해서 필요한 상황에만 자율적으로 스크립트 실행

1. 성능 저하(심각하면 DOWN으로 이어짐): CPU 사용률, Memory 사용률, 디스크 가용공간, 디스크 Inode 사용량, 디스크 사용률, 커넥션 사용량, 메모리 단편화율, Redis 메모리 사용률

2. 지금 당장의 장애는 아니지만, 장애 발생 시 무방비 상태(사후 분석 필수): Sentinel port 다운, Redis exporter 다운, Node exporter 다운

 

*exporter 다운: 프로메테우스가 해당 DB 상태(CPU, 메모리, 디스크 정보 ) 가져가지 못함. 즉각적인 장애는 아니지만, 실제 장애 상황일  프로메테우스가 장애를 인지하지 못하는 상황이 벌어질  있음

 

장애는 아님

1. Sentinel Failover: 마스터에 장애가 발생. 그래도 failover가 잘 수행되면 괜찮음

2. 삭제된 keys: 데이터 삭제는 장애로 볼 수 없음. 다만 Redis가 꽉 차서 캐시가 지워지는 eviction 경우라면 문제가 될 수 있지만 이는 위의 Redis 메모리 사용률 등으로도 충분히 파악 가능


Input 처리 방법

스크립트 실행 명령어에 '장애가 발생한 DB 서버의 hostname'을 input으로 추가

 

실행 명령어 예시: python3 스크립트명 hostname

*서버 내에서 직접 실행일 땐 hostname을 입력하지 않아도 동작하도록 구현

 

[이유]

  • 핵심: 실행 명령어가 사용자(담당자) 입장에서 복잡하지 않아야 함
  • 처음 아이디어(알람 내용을 그대로 복사 붙여넣기) 반려 이유: 실제론 알림을 복사 붙여넣기 하기 어려움, 복붙이 되더라도 오타 처리 및 알림 형식 파싱 복잡
  • 장애 결과(ex. MySQL Not Reachable, Redis Port Down)를 input에 넣는 아이디어: 스크립트 실행 시 모든 장애 원인을 다 찾아보는 것보단, MySQL Not Reachable → OOM, 디스크 full 등 장애 별 원인을 정해두고 해당 로그 파일들만 조회하는 것은 효율적인 로직
    하지만 반려 이유: 사용자의 편의 저하에 비해 코드 성능이 그렇게 좋아지는 것은 아님(사후 보고용 리포트 작성이 목적이므로 신속하게 처리되지 않아도 됨)
  • input에 '로그를 수집하고 싶은 시간'을 추가 반려 이유: 장애가 중복 또는 자주 발생하지 않는다는 점을 고려하면 시간을 입력하는 건 사용자 입장에서도 번거로움, '시간'을 input으로 넣어서 과거 로그를 확인하는 기능 필요없음
  • 하루에 최대 1가지의 장애만 발생함을 가정하지만, 만약 하루에 2가지 이상의 장애(ex. 오전에 한번, 오후에 한번)가 발생했을 때, '이 로그가 어느 장애와 관련된 로그인지'를 구분하는 건 고도화 부분으로 넘겨도 됨

장애 원인 탐지

장애  조사 우선순위는 다르게 설정하지 않아도 됨

[이유]

  • 장애 증상이 input에 없음
  • 특정 사소한 장애의 경우 불필요한 부분까지 조사하게 될 수 있지만, 타임라인 작성 작업은 천천히 이루어져도 되므로 상관 없음
  • 장애 상황도 자주 발생하지 않으므로, 로그 수집 작업이 장애가 발생한 서버에 과도한 부하를 주진 않을 듯

 

[성능 저하  일부 해당하는  + 모든 서비스 다운 증상 시 조사해야 하는 ]

*MySQL 기준

1. OOM killed(메모리 full)

  • OS 커널에서 확인: dmesg, syslog, 또는 journalctl에서 "Killed process ... out of memory" 포함 여부

2. 디스크 full 및 병목

  • SHOW INNODB STATUS 확인

3. CPU 병목

  • OS 커널에서 확인: Python psutil 등 이용

4. Too many connections

  • SHOW STATUS LIKE 'Threads_connected' 확인

5. 내부 로직 segfault

  • mysqld.err 파일 확인 또는 OS 커널에서 확인

 

[성능 저하 시에만 조사할 것]

1. 데드락 및 락 대기

  • SHOW INNODB LOCK 확인

2. 실행 계획 확인(인덱스 사용 여부, 조인 방식 등)

  • EXPLAIN [FORMAT=JSON] <쿼리>
  • 실행 계획을 확인하는 건 특정 쿼리 튜닝 작업 시 조사하도록 하고, 이 프로젝트에선 생략해도 됨

장애 최초 발생 시각 역추적 방식 후보군

  • Redis 종료/크래시 이벤트의 timestamp
  • 포트 리스닝이 사라진 흔적/재시작 흔적의 첫 시각
  • 헬스체크 실패(모니터링 로그)가 있으면 그 첫 시각
  • 아무것도 없으면: “탐지 시각 - 모니터링 interval” 같은 보수적 추정치

Output 형태

최종 Output은 https://ssuperjun.tistory.com/55 ([장애 이력 자동 작성 도구] Redis OOM 장애 상황 연출 게시글)

 

장애 지속 시간   : 9분 48초   (발생 → 해결)

발생 시각        : 2025-03-15 13:19:12
해결 시각        : 2025-03-15 13:29:00

장애 발생 원인   : OOM Kill

장애 타임라인
  13:19:12  [OOM] Feb 27 13:19:12 kernel: Out of memory: Kill process 1234
  13:21:00  [OOM] Feb 27 13:21:00 kernel: oom-killer invoked
  13:21:45  [OOM] Feb 27 13:21:45 kernel: Killed process 5678 (mysqld)
  13:22:30  [OOM] Feb 27 13:22:30 kernel: Out of memory: Kill process 9012
  13:28:30  [정상화] 2024-02-27T13:28:30.123456Z mysqld: ready for connections
  13:29:00  [정상화] 2024-02-27T13:29:00.789012Z mysqld: restarted successfully

앞으로의 계획

  1. Redis 설치
  2. Redis에 장애 발생시키기
  3. 장애 로그를 수집하는 스크립트 작성(OOM Killed 상황부터 구현 시작)
  4. 두레이 태스크로 등록
  5. Redis 센티널 설치 -> 마스터 다운, 복제 지연 등 상황 재현 -> 로그 수집 스크립트 작성

 

고도화 후보

  • 하루에 2가지 이상의 장애가 연달아 발생했을 때, '이 로그가 어느 장애와 관련된 로그인지'를 구분하기 => 그러려면 가장 마지막 장애 로그 묶음 시간을 저장하고 있어야 하나? 원래는 담당자가 장애해결 하나 끝나면 리포트 하나 쓰는 식으로 진행해야 하는데, 만약 여러 장애가 하나씩 다 해결되는 동안 스크립트를 한번도 안 돌렸다면 리포트가 작성 안된 가장 오래된 장애묶음부터 최근 장애묶음까지 리포트를 작성해야 하나? 아니면 리포트를 안쓴 장애묶음이 있다고 해도 가장 최근의 것 하나만 리포트를 작성해야 하나? => 일단 후자로 먼저 개발하고, 다 완성되면 전자로 고도화하거나 옵션 주고 전자 후자 둘다 가능하도록
  • 스크립트를 장애 직후 원인 파악 용도로도 사용하기
  • 장애 발생 직후 1차적으로 스크립트를 실행(원인 분석 및 휘발성 상태 정보 보존 목적) -> 1차 실행 때 수집한 정보를 사후 2차 실행에서 재활용하기
  • 그 외: 데이터 유실 방지 대책, 재해 복구, 저장장치별 일관성 유지 방법
  • 두레이 태스크 등록 알림 기능 추가, 시각화 및 장애 유형별 재발 빈도 통계, 비슷한 장애 사례 찾기, 알아서 장애 해결까지 자동화(너무 이상적임)

 

참고

처음 구상한 파이프라인(DB에 주기적 명령으로 장애 발생했나 로그 수집)을 왜 선택 안했는지, 이 파이프라인에 대한 설계도, 시간이 없어서 고도화 못한 부분 등은 최종 발표에 담아도 좋음


알람 종류

[ MySQL ]
CPU 사용률
시스템 다운
Memory 사용률
디스크 사용률
디스크 가용공간
디스크 Inode 사용량
디스크 error
복제 지연
복제 중단
슬로우쿼리
커넥션 사용량
MySQL 재시작
InnoDB Buffer Pool hit ratio
DB 접속 불가
MySQL exporter 다운
Node exporter 다운
Long 쿼리
Long 트랜잭션
쿼리 지연


[Redis]
CPU 사용률
시스템 다운
Memory 사용률
디스크 사용률
디스크 가용공간
디스크 Inode 사용량
디스크 error
Redis down
커넥션 사용량
reject된 커넥션
삭제된 keys
메모리 단편화율
Redis 메모리 사용률
Missing Master
복제 중단
Cluster Flapping
Sentinel Failover
Redis exporter 다운
Node exporter 다운
Redis port 다운
Sentinel port 다운