Incident Library
적용된 필터 구성 요소데이터베이스 복제증상지연 시간 증가기여 요인모니터링 사각지대모두 풀기검색어 없이 필터만 적용한 목록입니다. 최근 사례부터입니다.
추천 필터 검색하면 검색어에서 찾은 분류 값이 여기에 나옵니다.

그래프

  • 원인
  • 구성 요소
  • 증상
  • 기여 요인
  • 사례

사례4건

4건 중 1~4번째

  1. 증상

    9월 27일 22:58 UTC 에 쿼리 큐 깊이 알림이 울렸다. Azure West Europe 리전 고객의 쿼리가 느려지고 타임아웃됐다. 쓰기는 계속 받았지만 일부 파티션에서는 새 데이터를 바로 조회할 수 없었다.

    원인
    구성 요소
    기여 요인
    감지

    9월 27일 22:58 UTC 에 쿼리 큐 깊이 알림이 울려 장애 대응이 시작됐다.

    조치
    • 쿼리 계층 용량을 두 배로 늘렸다.
    • 9월 28일 아침에 멈춘 스토리지 파드를 하나씩 재시작했다.
    • 9월 29일 08:58 UTC 에 readiness 검사 타임아웃을 올려 전체에 배포했다.
    • 재시작 뒤 복구 동시성을 두 배로 늘렸다.
    • 9월 30일 00:25 UTC 에 정리 타임아웃을 24시간으로 올려 안전장치가 일으키던 강제 재시작을 멈췄다.
    • 스토리지 파드마다 자원 요청을 올려 호스트에 올라가는 파드 수를 줄였고, 파드마다 페이지 캐시용 메모리와 디스크 처리량이 두 배가 됐다.
    후속 조치
    • 페이지 폴트 비율, 캐시 커버리지, 스토리지 볼륨의 디스크 읽기, 쿼리 중단 비율에 경고 알림을 더했다. 알림은 캐시 압박이 고객에게 보이기 전에 울리도록 만들었다.
    • 런북에 major page fault 를 스토리지 성능 저하의 선행 지표로 적고, 조정할 수 있는 완화 설정을 자세히 적었다.
    • 스토리지 엔진의 참조 누수를 계속 추적한다.
    • 디스크 검사를 상태 검사 경로에서 뺀다.
    교훈

    캐시가 모자란 상태는 메모리 지표에 드러나지 않았다. 스토리지 프로세스가 메모리를 적게 쓰고 나머지를 페이지 캐시가 차지하기 때문이다. InfluxData 는 major page fault 를 스토리지 성능 저하의 선행 지표로 본다. InfluxData 는 스토리지 엔진의 참조 누수와 상태 검사 경로의 디스크 검사가 이런 장애를 일으키는 위험 요인은 아니며, 진단과 복구 중에 눈에 띄어 조사할 만한 현상이라고 밝혔다.

  2. 증상

    2022년 11월 23일 9:39 UTC 에 트래픽 전부가 새 Aurora PostgreSQL 14.x 클러스터로 넘어갔고, 지연이 나빠져 인프라 팀이 조사를 시작했다. 9:54 UTC 에는 쿼리가 평소보다 훨씬 오래 걸리면서 데이터베이스 연결을 모두 차지하고 있었다.

    촉발

    복제를 이용해 Aurora PostgreSQL 10.x 클러스터에서 새 14.x 클러스터로 트래픽을 넘겼다. 그런데 가장 큰 테이블 하나의 vacuum 이 전환 전에 끝나지 않아, 새 클러스터의 가장 큰 테이블들에 ANALYZE 가 돌지 않은 상태였다.

    원인
    구성 요소
    기여 요인
    감지

    9:39 UTC 에 트래픽 전부가 새 클러스터로 넘어갔을 때 지연이 나빠 보였고, 인프라 팀이 바로 조사를 시작했다.

    조치
    • 9:54 UTC 에 쿼리가 데이터베이스 연결을 너무 오래 잡지 않도록 데이터베이스 사용자에 statement timeout 을 걸었다.
    • 9:58 UTC 에 로드 밸런서에서 트래픽의 90% 에 503 을 보내 부하를 덜고 시스템이 회복할 여유를 만들었다.
    • 10:00 UTC 무렵부터 오래 걸리는 쿼리에 EXPLAIN 을 돌려 보고, 해만 끼치고 필요 없는 인덱스를 지우기 시작했다.
    • 트래픽을 100% 로 되돌리는 동안 Apple 웹훅을 잠시 받지 않았다.
    • New Relic 이 느린 쿼리마다 돌리는 EXPLAIN 쿼리를 없애려고 New Relic 을 끈 새 릴리스를 냈다.
    • 12:00 UTC 무렵부터 가장 큰 테이블들에 손으로 ANALYZE 를 돌렸다.
    • 미리 준비해 둔 스크립트로 영향받은 시퀀스 값을 자동으로 올려 기본 키 중복을 풀었다.
    • 전환 몇 분 뒤 통합 이벤트 발송 작업이 이벤트 테이블을 갱신하지 못하는 것을 잡고 발송 작업을 손으로 멈췄다.
    • 발송되었지만 데이터베이스에 기록되지 않은 웹훅을 만일에 대비해 다시 보냈다.
    • 13:33 UTC 에 통합 이벤트 발송, ETL, 웹 서버 밖의 작업을 모두 되살렸다.
    후속 조치
    • 사업에 중요한 시기에는 변경 동결을 두는 것을 검토한다.
    • 백엔드 장애 때 SDK 가 얼마나 믿을 만하게 동작하는지 더 잘 알린다.
    • 개발자 대시보드와 기술 담당자에게 보내는 직접 이메일을 써서 유지보수와 장애를 고객에게 더 잘 알린다.
    • 사전 연습에서 트래픽 일부를 재생해 전환 당일과 더 비슷한 조건을 만든다. 이번 연습은 쓰기 트래픽을 재생하지 않았다.
    • API 를 빠르고 안정적으로 유지하려고 비용이 큰 작업을 최대한 비동기로 옮기는 데 더 투자한다.
    • 테이블 인덱스를 다시 검토한다. 쓰이지 않는 인덱스가 있고, 데이터베이스가 쿼리에 그 인덱스를 고르면 성능이 떨어질 수 있다.
    • 데이터베이스 대시보드에서 엔드포인트와 시스템별 부하를 더 잘 보여 줘 부하가 어디서 오는지 빨리 찾게 한다. 이번에는 Apple 웹훅 부하가 복구를 막는다는 것을 아는 데 너무 오래 걸렸다.
    • 장애 중에 고객 지원과 고객 커뮤니케이션 담당을 불러 소통을 맡긴다.
    교훈

    RevenueCat 은 처음부터 롤백했으면 더 나았다고 돌아봤다. 사전 연습에서는 데이터 일관성과 쿼리 성능만 보고 쓰기 트래픽을 재생하지 않았다. 쓰기는 인덱스가 얽히지 않아 읽기보다 단순하다고 여겼기 때문이다. 복제를 멈추고 평소처럼 쓰기를 해 봤다면 문제를 찾을 수 있었다. 시퀀스 상태가 복제되지 않는다는 한계를 놓치고 상태도 함께 복제된다고 가정했다. 사전 연습 때는 새 클러스터가 오래 떠 있어 vacuum 과 통계가 이미 끝나 있었기 때문에 ANALYZE 가 없는 문제를 보지 못했다. 시기로는 추수감사절과 블랙 프라이데이 전에 끝내려 했지만, 미국 지원팀 일부가 이미 휴가 중인 민감한 때였으므로 그다음 주로 미뤘어야 했다고 밝혔다.

  3. 증상

    Aurora MySQL 의 reader 가 이유를 알 수 없이 재시작했다. 그 직후부터 writer 의 insert latency 가 7배쯤 오르는 등 writer 성능이 크게 떨어진 상태가 오래 이어졌다. 같은 일이 2019년 11월 두 주 사이에 두 번 일어났다.

    촉발

    reader 에서 오래 도는 쿼리 때문에 롤백 세그먼트가 계속 커진 끝에 reader 가 재시작했다. 글쓴이는 그 쿼리가 Redash 에서 reader 로 보낸 것이었다고 기억한다.

    원인
    구성 요소
    기여 요인
    조치
    • 팀은 writer 성능이 원래대로 돌아올 때까지 지켜보기만 했다.
    후속 조치
    • 롤백 세그먼트 길이를 Datadog 의 mysql.innodb.history_list_length 로 감시하는 모니터를 더했다.
    • reader 가 재시작할 만큼 오래 도는 쿼리를 찾으면 바로 kill 하게 했다.
    • 모니터 알림이 거의 매주 울리게 되자 사내에 알린 뒤 max_execution_time 을 설정해, 일정 시간이 지난 쿼리를 강제로 끝내게 했다.
    교훈

    롤백 세그먼트가 커지지 않도록 트랜잭션을 작게 해야 한다. 롤백 세그먼트는 클러스터 전체가 함께 쓰므로, 한번 커지면 인스턴스를 바꿔도 해제가 끝나기를 기다리는 수밖에 없다. 롤백 세그먼트 길이는 show engine innodb status 의 "History list length" 값으로 볼 수 있다.

  4. 증상

    WORKER_JOB_ERROR 오류가 늘었다는 신고가 들어왔다. 이 오류는 파일을 받아 Assembly 를 조율하는 Uploader 와 인코딩을 실행하는 Drone 사이의 통신에 문제가 있다는 뜻이다.

    촉발

    HLS 트래픽이 가파르게 늘었고, 같은 양을 더 빨리 처리하려고 Drone 을 더 많이 띄울 수 있게 되면서 중앙 노드가 바빠졌다. 이를 설명할 코드나 인프라 변경은 찾지 못했고, 이 두 변화가 겹쳐 Redis 병목이 드러났다.

    원인
    구성 요소
    기여 요인
    감지

    WORKER_JOB_ERROR 오류가 늘었다는 신고가 들어와 문제를 알았다. 모니터링은 Redis 명령 수, 연결 수, 스왑 사용량을 보고 있었지만 대역폭은 보지 않아 포화를 잡지 못했다.

    조치
    • 잃은 메시지를 다시 넣고 하트비트 감시를 느슨하게 하는 임시 조치를 했다. 증상만 막는 조치였고 Assembly 실행 시간이 늘었다.
    • 놓친 Redis 패치가 있는지 확인하고 Redis 를 최신 안정 버전으로 올렸다.
    • 대역폭 제한에 걸린 것을 알고 Redis 클러스터를 두 배인 여섯 대로 늘렸다. 곧 다시 포화되자 세 대를 더 붙였지만 상황은 더 나빠졌다.
    • 읽기 replica 를 하나로 줄였다. 트래픽과 실패율이 바로 떨어졌고 Assembly 가 다시 빨라졌다.
    • 리전마다 Drone 확장에 상한을 두었다. 큰 배치 가져오기는 시간이 더 걸릴 수 있지만 시스템은 안정을 유지한다고 밝혔다.
    후속 조치
    • 포화 수준에 다시 가까워지면 알 수 있도록 로그와 알림을 더 둔다.
    • Redis 노드와 Drone, Uploader 사이의 트래픽을 한곳에 몰리지 않게 나눌 방법을 찾는다.
    • 이미 하고 있는 리전별 샤딩에 더해 Uploader 별 샤딩을 추가한다.
    교훈

    Redis 노드를 늘린 것은 잘못된 판단이었다. 모든 쓰기를 리더 한 대가 받는 구조에서는 노드가 늘수록 리더가 복제로 내보낼 트래픽이 늘어, 더 많은 트래픽을 감당하려면 노드를 오히려 줄여야 했다. 잃은 데이터를 다시 넣을 수 있으므로 팀은 복제가 꼭 필요한지 다시 따져 봤다. 지표는 이미 많이 지켜보고 있었지만 알림을 제대로 걸 수 있는 지표는 몇 개뿐이어서, 고른 지표가 모자랐을 수 있다. 대역폭도 빠져 있었다. 쓰기를 받는 Redis 노드가 하나뿐이면 replica 를 줄이거나 노드를 키워도 시간을 조금 벌 뿐이고, 성장을 버티려면 트래픽을 나눠야 한다.

내 클러스터에도 있는지 확인하기

이 4건에서 가장 많이 나오는 구성 요소: 데이터베이스 복제, 데이터베이스. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.

원인별2