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

[(가칭)장애 대응 프로젝트0] 구상 본문

인턴

[(가칭)장애 대응 프로젝트0] 구상

ssuperjun 2026. 2. 12. 14:33

프로젝트명 예시

장애 대응 프로젝트

장애 이력 자동 작성 도구

 

프로젝트 방향성

  1. 장애 발생했을 때 타임라인 두레이에 정리해주는 도구
  2. 알림 기능 추가
  3. 시각화 및 장애 유형별 재발 빈도 통계
  4. 비슷한 장애 사례 찾기
  5. 알아서 장애 해결까지 자동화

이 중 1번 부분만 구현하기

나머지는 1번이 완료된 후 고도화 부분에 해당

 

파이프라인 후보군

1. 수집 대상 DB(Mymon DB에 정리돼 있음) --주기적 쿼리--> 로그 수집 및 저장 -> Transformation -> 장애 조건에 부합하는 로그 판별 -> 장애 로그만 Transformation -> output(두레이 태스크로 등록)

2. logDB에 저장된 로그 --주기적으로 가져오기--> 장애 로그 판별 -> Transformation -> output

3. alert 발생 -> 수집 대상으로부터 로그 수집, 정제(or 알람 히스토리가 이미 충분히 정리돼 있다면 그냥 가져오기) -> 장애 원인 파악 -> Transformation -> output

 

1번이 정배

logDB 자체가 죽어버리면 2번 방법은 불가능, 1번 방법만 가능

3번 방법은 회사 자체적으로 모니터링 alert가 존재한다고 가정하고 고안함

어떤 게 장애인지에 대한 기준을 명확히 하는 게 중요(ex. 비효율 쿼리 정의 어떻게? - N초 이상 쿼리 비율이 X% 이상 등)

 

26.2.13 추가

멘토님은 3번을 제안함

alert 프로세스를 알지 못해서 3번은 배제해뒀는데, alert가 언제 어떻게 발생하는지만 안다면 3번이 더 괜찮을 것 같음

 

[이유]

장애가 그리 빈번하게 일어나는 이벤트도 아니고

process list 및 innodb 정보 수집 프로젝트 당시, 수집 대상 DB가 많아 1초 주기로도 수집이 밀리는 문제가 있었음

1번처럼 처음부터 생으로 수집하는 것 대신, 2번처럼 수집 부분 난이도를 낮추고

장애 난 상황은 alert로 인지 -> 장애 난 서버에 대해서만 조사를 진행

이 방식으로 하는 게 좋아 보임

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

 

[주요 고려사항]

실제 알람이 어떻게 오는지 파악 필요

 

알람 예시

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!

 

결론

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

 

참고

알람을 받은 이후 담당자들은 원인 파악보다 선조치로 서비스 정상화를 먼저 진행할 수 있음(원활한 서비스 위해)

이후 상황 보고를 위해 stop/down 등의 원인 및 정상화까지의 시간 순서대로 이력을 기록해야 함 -> 프로젝트의 목적


2번 관련: logDB에 이미 있는 정보(process list, innodb status, innodb lock)들도 가져와서 장애(디스크 full, 메모리 부족) 감지에 활용해도 되나?

=> 장애 시점의 상태 정보를 가져오는 용도로 활용할 수 있겠지만, 장애 상황은 이미 alert로도 파악 가능한 이유 등으로 logDB의 정보는 굳이 활용하지 않아도 됨

 

장애관리 프로세스

1. 장애 발생

2. Task 생성 -> 이번 프로젝트에 해당하는 부분

3-1. 전파(장애관리팀만)

3-2. 업데이트(Task 내용)

4. 장애 해결

5. 후속 조치 -> 고도화한다면 이 부분

6. 장애 종료

 

일단 이 프로젝트는 장애 발생 당시에 대한 상황을 정리하는 것이지, 장애 해결까지 처리하는 건 아님

=> 장애관리 프로세스 장애해결 전까지만 염두하면


장애 기준 선정

무엇이 장애인가

로그를 보고 어떤 장애인지, 원인이 뭔지 파악할 있는가

감지할 장애 종류(증상-원인 매칭)

1. DB 서비스 다운 / 먹통

  • 자원 포화: OOM(Out of Memory)으로 인해 OS가 DB 프로세스를 강제 종료 (OOM Killed), 디스크가 꽉 차서 DB 강제 종료, 최대 연결 수 초과 (Too many connections)
  • 내부 코드 오류: 로직 수행 도중 segfault 등으로 비정상 종료되면 로그 발생

2. 성능 저하: 쿼리 수행 지연

  • 디스크 I/O 병목, CPU 사용률 100% 지속
  • 비효율 쿼리 및 락: 인덱스 풀 스캔(풀스캔이더라도 비효율을 장담할 순 없음), 데드락(Deadlock found), 락 대기(Lock wait timeout) 등

26.2.13 추가

3. 마스터-슬레이브 데이터 불일치

  1. 자원 포화: 슬레이브 서버의 리소스 부족으로 마스터의 변경 속도를 못 따라감
  2. 의존성 문제: 마스터-슬레이브 간 통신 등 외부 요인 장애

 

[고려사항]

메모리 부족을 이유로 OS가 DB를 강제로 죽이면 로그가 안 남음. 그래도 종료 로그 없이 재시작 로그가 나오는 것만으로도 비정상 종료임을 판별할 수 있음. 근데 이건 주먹구구식인 것 같음

=> OS 커널 로그를 수집도 고려해보자

=> sudo 권한이 중요한데, irteamsu로 접속하면 가능


내가 최종 선정한 핵심 장애 종류

주요 증상 <-> 원인 매칭

  1. DB 서비스 다운 / 먹통
    1. 자원 포화: OOM(Out of Memory)으로 인해 OS가 DB 프로세스를 강제 종료 (OOM Killed), 디스크가 꽉 차서 DB 강제 종료
    2. 내부 엔진 버그: 프로그램 비정상 종료를 발생시키는 치명적 오류 (Segfault, Assertion failure), 자동화 스크립트 오류(failover, role change, evacuate 등)
  2. 성능 저하: 쿼리 수행 지연
    1. 자원 포화: 디스크 I/O 병목, CPU 사용률 100% 지속
    2. 비효율 쿼리 및 락: 인덱스 풀 스캔, 데드락(Deadlock found), 락 대기(Lock wait timeout)
  3. 연결 오류: 클라이언트나 애플리케이션이 DB에 접속하지 못함
    1. 자원 포화: 최대 연결 수 초과 (Too many connections)
    2. 설정 및 권한 문제: 잘못된 계정 정보, IP 차단 (Access denied)
    3. 네트워크 및 클라이언트 이탈: 방화벽 문제, 네트워크 단절 (Aborted connection)
  4. 마스터-슬레이브 데이터 불일치
    1. 자원 포화: 슬레이브 서버의 리소스 부족으로 마스터의 변경 속도를 못 따라감
    2. 의존성 문제: 마스터-슬레이브 간 네트워크 스토리지 등 외부 요인 장애

*데이터 손상 / 유실: 데이터 파일 자체가 깨지거나 트랜잭션 유실은 DB 서비스 다운 / 먹통의 결과임 => 후속 조치에 해당

*연결 오류는 db만의 문제가 아니므로 패스

*마스터-슬레이브 데이터 불일치를 이 프로젝트에서 장애 상황으로 넣어야할까 말아야할까? 모니터링 대상 서버 중 마스터-슬레이브 관계의 db가 존재하나? 단순히 복제 지연을 장애라고 볼 수 있는가?

 

장애 원인 중 사람 개입이 필요한 원인

  1. 작업 프로세스 없음
  2. QA 사전 테스트 부족?
  3. 부서 커뮤니케이션 문제
  4. 통신사, 전력 외부 요인으로 인한 문제

=> 사람 개입이 필요한 원인까지 탐지할 수 있을진 모르겠음. 여기선 제쳐둠


Output(두레이 태스크에 등록될 항목)

타임라인 = 장애 발생 시점부터 정상화 시점까지의 단위 시간별 장애 이력(언제 어디서 문제가 발생했고 언제까지 계속 발생했는지)

반드시 넣기

    • 발생 시각
    • 탐지 시각
    • 인지 시각
    • 담당자 인지 방법(장애 접수 채널. 죄다 '이 프로젝트’로 기입하면 됨)
    • 장애 발생 원인(중요. 이 프로젝트의 핵심)
    • 장애 처리 부서
      • 프로젝트에선 db 관련된 장애만 수집하므로 죄다 '데이터운영으로 기입하면 됨
      • db 복합적인 문제라도 최초 발견은 '데이터운영’ 부서가 했으므로 '데이터운영으로 기입해도 문제는 없을

장애관리팀 작성 영역이지만 output에 넣으면 좋을 부분

  • 장애 제목
  • 장애 등급
  • 주요 증상
  • 대상 리전
  • 장애 접수 채널(alert라면 alert로 기입)
  • 장애 처리 결과(죄다 진행중으로 넣으면 됨)
  • 탐지 지속 시간(장애 발생부터 탐지까지 걸린 시간)
    • 탐지 시각은 프로그램이 '수집한 로그를 장애라고 판정한 시각' 또는 alert 발생한 시각
  • 인지 지속 시간(장애 탐지부터 인지까지 걸린 시간)

*장애관리팀 = NHN Enterprise 산하 장애관리팀을 의미한다고 가정

굳이 들어가야 되나 싶은 부분

  • 공지 게시 시각
  • 공지 시간

=> 그냥 인지 시각 값과 동일하게 작성하면 될 듯

 

구현 가능할지 모르겠는 부분

  • 영향 범위
    • 장애 대상 고객사
    • 인프라 영향 범위 - 예를 들어 하이퍼바이저 장애라면 영향받은 VM 목록. 네트워크 장비 장애라면 영향받은 서비스 목록
    • 서비스 영향 범위 - 예시: 고객 VM 생성 불가, 홈페이지 접속 불가
  • 변경작업에 의한 장애인지 여부(고도화 후보1)
    • 정기점검이나 장비 업그레이드 직후 발생했다면 관련 태스크 링크 첨부
    • 이게 가능하려면 정기점검 정보도 수집해서 저장하고 있어야
    • 변경 작업 직후 장애가 발생했어도, 장애의 실제 원인이 변경 작업인지는 알기 어려움
    • => 장애 타임라인을 이 프로그램이 자체적으로 판단해 결과를 내는 건 어려우므로 일단은 배제
  • 반복장애(고도화 후보2)
    • 이게 가능하려면 과거 장애 이력, 종류 정보도 수집해서 저장하고 있어야
    • => 하면 좋지만 우선 구현할 기능은 아님

장애해결 이후에 작성될 부분

  • 해결 시각
  • 장애 지속 시간(장애 발생부터 해결까지 걸린 시간)
  • 처리 지속 시간(장애 인지부터 해결까지 걸린 시간)
  • 후속 조치 체크리스트
  1. 공통 유형
    • 이중화 구성 문제
      • 이중화 구성이 되어있지 않거나 이중화 처리가 정상적으로 진행되지 않아 서비스 영향이 발생한 경우
    • 데이터 유실 문제
      • 데이터 누락, 데이터 재처리 불가 등으로 인한 수집 불가 등의 유실 문제가 발생한 경우
  2. 원인 분석 불가 유형
    • 재현 불가
    • 로그 확보 불가능
  3. 인프라 유형
    • H/W Fault
      • 장비명, 장비 파트 위치/넘버 등 H/W 정보에 대해 기재해 주세요
    • S/W 문제
      • 어떤 S/W에 문제가 있었는지 상세하게 기재해 주세요 (OS, 드라이버, 펌웨어, 프로세스 명 등등)
  4. 상품/서비스 유형
    • 코드 문제
    • 설정 문제
    • 리소스 문제
    • 의존성 문제
      • 본 장애로 인해 다른 서비스가 영향을 받은 경우 체크해 주세요(연관 장애)
  5. 프로세스 유형
    • 자동화 관련 문제
      • 자동 스크립트, failover, role change, evacuate 문제 등으로 인한 문제인 경우 체크해 주세요
    • 테스트 미흡 문제
      • 사전 테스트가 미흡했던 경우 체크해 주세요
    • 프로세스 없음
      • 본 장애에 대한 절차 및 작업 프로세스가 없는 경우 체크해 주세요
  6. 인적 장애 유형
    • 프로세스/정책 미 준수
      • 작업 간 프로세스/정책을 준수하지 않아 발생한 장애인 경우 체크해 주세요(작업계획서 검토 누락 등 포함)
    • 의사 소통 문제
      • 타 부서간 커뮤니케이션 오류(정보 전달 누락, 변경 요청/승인 절차 누락 등)로 인한 문제인 경우 체크해주세요
  7. 외부요인
    • 외부 요인(통신사, 전력, 타 벤더)으로 인한 장애

기타

고객 문의 -> 담당자 확인 -> 어디가 문제지? 로그 뒤져 봄

이런 고객 문의에 대한 장애 원인 파악 부분은 자동화하기 어려워 보임

고객 문의 -> 파싱 -> 장애 발생 가능 후보군(db, 네트워크 장비 등에서 추려야 )에서 로그 수집 -> 저장 -> 장애 판별 원인 파악( 로직 매우 복잡 예상) -> Transformation -> 두레이 태스크로 등록

 

그 외 고민

고민1: 담당자의 확인 없이 장애 이력 태스크를 자동 등록하게 할까? 아니면 작성시켜 놓은 담당자가 확인 후에 클릭 한번으로 등록되도록 할까?

=> 담당자가 alert 발생 시 '장애 이력 생성' 스크립트를 실행한다면 바로 공지로 올려도 됨

혹은 공지 전에 팀 내부 공개용 태스크만 올려도 됨. 이후 공지에 올리는 건 담당자가 최종 수정 후 올리기

 

고민2: output을 두레이에 바로 올릴까?

=> 이게 안되면 웹에 띄워도 괜찮음

 

고민3: github 써도 되나?

=> MySQL 도구 구현 담당 팀원과 Redis 도구 구현 담당 팀원 간 코딩 스타일은 달라도 되므로 코드 충돌은 안 나겠지만

output을 어차피 합치므로 미리 각자의 폴더를 github에 올려두고 git으로 편하게 작업하는 게 괜찮아 보임


로그 수집 방식

Promtail 같은 로그 에이전트 사용 vs Python 스크립트를 데몬 프로세스로 활용

  • 로그 에이전트는 별도의 설치가 필요하므로, 간편하면서도 익숙한 방식인 후자를 선택
  • 또한 cron과 달리 매번 프로그램을 새로 시작하는 방식이 아닌, 계속 실행하는 데몬 프로세스이므로 오버헤드 x

→ Python 데몬 프로세스 채택

 

MySQL 장애상황 연출

- 강제로 kill

- 로직으로 죽이기: 임시 테이블에 데이터 insert 한꺼번에 또는 select 한꺼번에 실행


장애 대응 프로젝트6 - 알람 중요도 구분

 

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

 

[ MySQL ]

 

*이 알람이 뜨면 로그 수집 스크립트를 실행해야 함

 

시스템 다운, MySQL 재시작: 매우 중요

디스크 가용공간, 디스크 Inode 사용량, 디스크 error, 커넥션 사용량, DB 접속 불가: DB 서비스 먹통과 관련

복제 지연, 복제 중단: 마스터-슬레이브 간 장애

CPU 사용률, Memory 사용률, 디스크 사용률, 슬로우쿼리, InnoDB Buffer Pool hit ratio, Long 쿼리, Long 트랜잭션, 쿼리 지연: 성능 저하와 관련

 

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

 

MMM 롤체인지: DB 서버의 역할이 바뀌었다 = 마스터가 죽었다는 뜻

MMM VIP ping check: MMM 가상 IP DB 서버에 띄워서 애플리케이션이 접속하도록 하는데, 알람은 앱이 접속할 (VIP) 사라진 경우 발생(서비스 접속 불가)

MMM 모니터 Active: MySQL 서버들의 감시자인 MMM이 죽음. 즉각적인 장애는 아니지만, 마스터가 죽게 되면 failover(슬레이브 승격) 불가능

 

참고: MMM은 MySQL 서버들의 상태를 감시함. 마스터가 죽으면 슬레이브를 승격시키는 failover를 실행하고, 가상 IP(VIP)를 이동시켜 지속적인 서비스를 제공함

 

 

[Redis]

CPU 사용률

시스템 다운

Memory 사용률

디스크 사용률

디스크 가용공간

디스크 Inode 사용량

디스크 error

Redis down

커넥션 사용량

reject된 커넥션

삭제된 keys

메모리 단편화율

Redis 메모리 사용률

Missing Master

복제 중단

Cluster Flapping

Sentinel Failover

Redis exporter 다운

Node exporter 다운

Redis port 다운

Sentinel port 다운


[고민거리]

비효율 쿼리 정의 어떻게?

N초 이상 쿼리 비율이 X% 이상 등

수집 주기 어떻게?

각 단계별 어떤 기술 쓸지

그 외: 데이터 유실 방지 대책, 저장장치별 일관성 유지 방법

 

26.2.19

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

 

담당자가 alert 인지 -> 스크립트 실행

해당되는 DB 서버에서 로그 수집(알람 종류별로 실행할 명령, 조사할 부분 다름) -> 분석 및 임시 기록(Output 작성 중) -> Output(두레이 태스크)

 

알람 종류별로 실행할 명령, 조사할 부분 다름 관련 26.2.23 추가

멘토님도 장애 유형별로 우선적으로 확인할 로그를 미리 정해두고 그 범위 안에서 탐색하는 방식이 더 좋다고 함

(장애 발생 시간대를 기준으로 로그를 넓게 필터링해서 전체를 조회하는 방식보단)

 

[고민거리]

장애 시작 시점 찾기: alert를 받은 시점 직전 1분 전부터 조사? 아니면 alert에서 제공한 시각이 곧 장애 시작 시점인가? 언제부터의 로그를 분석에 사용할 건지?(종료 시점은 별 문제 안됨)

알람 중요도 구분하기

 

수집 주기(1번 파이프라인 선택 시에만 고려)

데몬 프로세스로 30초 주기? 로 로그 수집

장애 이력을 정리해주는건데 1초 단위로 주기를 짧게 가져가는 게 굳이 필요할까 싶음

수집 주기가 너무 짧으면 DB에 부하를 줌

processlist 및 innodb-lock 수집은 10초 주기로, innodb-status 수집은 1분 주기로 수집하는 식으로 데이터 성격에 따라 수집 주기를 다르게 가져가는 것도 좋은 방법

 

——

 

db나 os에 명령어를 날려 로그 수집하기

목적: 장애 증상과 원인 탐지

 

장애 증상별 탐지 방법

  1. 서비스 다운 / 먹통
    1. 로그에서 "Connection Error" 확인([202X-XX-XX 14:00:00] DB 접속 불가 (원인: 2003 Can't connect to MySQL server))
    2. mysqld.err 또는 OS 로그에서 segfault 확인되면 이 증상으로 규정하기
  2. 성능 저하
    1. 자원 포화(os 메모리 full, 디스크 full, 디스크 병목, cpu 병목, too many connections 등), 비효율 쿼리 및 데드락 등의 장애 원인 탐지 시 이 증상으로 규정하기
  3. 마스터-슬레이브 데이터 불일치

 

*단순히 복제 지연을 장애라고 볼 수 있는가?

 

장애 원인별 탐지 방법

    1. OOM killed
      1. logDB로 파악 불가
      2. dmesg, syslog, 또는 journalctl에서 "Killed process ... out of memory" 포함 여부
    2. 디스크 가득 참
      1. logDB로 파악 불가(디스크 I/O 상태는 존재하지만 디스크 full 여부는 파악 불가)
    3. Too many connections
      1. logDB의 processlist와 관련있긴 하지만
      2. SHOW STATUS LIKE 'Threads_connected' 명령으로 감지하는 것도 필요할 듯
    4. 내부 오류(segfault 등)
      1. logDB로 파악 불가
      2. mysqld.err 또는 OS 로그 분석 필요

          1. 디스크 병목
            1. logDB innodb-status 테이블에서 디스크 I/O로 파악 가능
          2. CPU 병목
            1. OS레벨 CPU 사용률은 Python psutil 이용
            2. DB 내부에는 자체적인 CPU가 없다. OS로부터 자원을 빌려씀
          3. 비효율 쿼리 / 락
            1. logDB의 processlist로 비효율 쿼리 파악 가능
            2. logDB의 innodb_lock으로 데드락 파악 가능
        1.