사례5건
5건 중 1~5번째
- 증상
2026년 10월 6일 13시 30분 UTC부터 CircleCI 의 워크플로 조율 서비스가 느려져 일부 파이프라인과 잡이 이따금 조금씩 늦게 시작했다. 15시 30분부터는 지연이 계속 이어졌고 일부 잡이 실패하기 시작했다.
- 촉발
10월 6일 12시 40분쯤 데이터베이스의 가장 큰 테이블 몇 개에서 돌던 정기 유지 보수 작업인 anti-wraparound autovacuum 이 평소 작업량과 겹치면서, 데이터베이스가 트랜잭션 로그를 보관 처리하는 속도보다 빠르게 로그를 썼다.
- 원인
- 구성 요소
- 기여 요인
- 감지
10시 2분부터 모니터링이 조율 서비스의 오류 알림을 짧게 여러 번 냈지만 매번 저절로 풀렸다. 13시 35분에 여러 다른 서비스의 관련 알림과 함께 다시 울렸고, 14시 30분쯤 알림이 다시 울리자 더 조사한 뒤 14시 54분에 장애를 선언했다. 트랜잭션 로그 볼륨이 얼마나 찼는지와 보관 처리가 얼마나 밀렸는지를 보는 알림은 없었다. 상태 페이지에는 15시 58분에 공지를 올렸고 16시 20분에 주요 장애로 올렸다.
- 조치
- anti-wraparound autovacuum 이 빨리 끝나도록 설정을 바꿨다. 이 작업은 취소하면 데이터베이스가 자동으로 다시 시작하기 때문이었다.
- 트랜잭션 로그 볼륨이 거의 차자 데이터베이스가 읽기 전용이 되지 않도록 로그를 여유 공간이 많은 데이터베이스의 주 저장 볼륨으로 옮겼다. 옮기는 동안 데이터베이스가 50분 동안 내려갔다.
- 유지 보수 작업이 더 시작되지 않도록 데이터베이스 파라미터 몇 가지를 조사해 바꿨다.
- 18시 19분에 쓰기마다 저장소를 기다리는 시간을 줄이는 데이터베이스 설정을 바꿔 처리 속도를 되살렸다.
- 밀린 작업을 빨리 처리하려고 잡을 실행 플릿에 넘기는 시스템에 데이터베이스와 서버 용량을 더했다.
- 후속 조치
- 트랜잭션 로그 볼륨이 얼마나 찼는지와 보관 처리가 얼마나 밀렸는지에 알림을 건다.
- 이 두 상태를 일으키는 데이터베이스 유지 보수 작업에도 알림을 걸어 더 일찍 대응한다.
- 시끄럽거나 지나치게 민감한 알림이 실제 문제를 가리지 않도록 모든 알림을 다시 살핀다.
- 데이터베이스의 autovacuum 이 얼마나 자주, 얼마나 공격적으로 도는지를 조정한다.
- 큰 테이블들의 크기를 시간에 따라 추적해 안전한 한계 안에 두게 한다.
- 트랜잭션 로그 하나에 모든 쓰기가 몰리는 병목을 없앤다. 서비스를 각자 트랜잭션 로그를 가진 여러 데이터베이스 인스턴스로 나누는 방법과, 쓰기를 여러 노드에 나누는 분산 데이터베이스로 옮기는 방법을 검토한다.
- 다른 시스템들이 재시도 끝에 포기하지 않고 조율 서비스가 회복할 때까지 기다리도록 동작을 바꾼다.
- 긴 장애 동안 상태 페이지 공지가 구체적인 영향과 시각을 더 일찍 담도록 지침을 고친다.
- 교훈
CircleCI 는 여러 알림이 함께 울린 것을 더 일찍 알아챘어야 했다고 밝혔다. 모니터링은 느려진 것을 잡았지만 트랜잭션 로그 볼륨이 찬 정도와 보관 처리가 밀린 정도에는 알림이 없었다. 조율 서비스의 모든 쓰기가 데이터베이스 하나와 트랜잭션 로그 하나를 거치기 때문에, 그 로그가 밀리자 모든 파이프라인, 워크플로, 잡이 함께 느려졌다. 일부 잡은 다른 시스템들이 재시도 끝에 포기해서 실패했다. 고객들은 초기 상태 페이지 공지에 세부 내용이 부족했다고 알려 왔다.
IL-0288CDN77 의 ClickHouse 데이터 파이프라인에서 이중화된 인스턴스 세 곳의 ZooKeeperWait 가 수천 초로 치솟아 복제가 한 시간 넘게 느려졌다CDN772026- 증상
13:30 UTC 에 ZooKeeperWait 지표가 갑자기 오른다는 알림이 왔다. 이 클러스터의 알림 기준은 낮은 쪽 10초, 높은 쪽 20초인데 값은 수천 초였다. 값은 대칭으로 이중화된 인스턴스 세 곳에서 똑같이 올랐다.
- 촉발
몇 달 동안 네트워크에서 떨어져 있던 클라이언트 머신 두 대가 다시 연결되면서, 그동안 쌓인 몇 달 치 헬스 체크 데이터를 아주 작은 배치로 빠르게 보냈다.
- 원인
- 구성 요소
- 기여 요인
- 감지
13:30 UTC 에 팀은 ZooKeeperWait 지표가 갑자기 오른다는 알림을 받았다. 이 클러스터 크기에 맞춘 알림 기준은 낮은 쪽 10초, 높은 쪽 20초였다.
- 조치
- 쌓인 파트를 끝내 정리하지 못한 5분 단위 파티션 테이블을 장애 뒤 DROP-CREATE 로 다시 만들어 정상으로 되돌렸다.
- 그 테이블의 파티션 단위를 분에서 시간으로 넓혔다.
- 후속 조치
- 루트 MaterializedView 테이블에서 범위를 벗어난 타임스탬프를 거부하도록 구현했다.
- 두 번째 MaterializedView 가 거부된 데이터의 통계를 기록한다.
- 거부 범위는 과거 데이터 백필을 위해 일부러 넓게 잡았고, 거부되는 데이터를 모아 가며 범위를 다듬는다.
- 타임스탬프가 며칠이나 몇 달에 걸친 insert 쿼리 하나로 이번 상황을 재현하는 최소 시험 시나리오를 만들었다.
- 관측 기능을 여러 가지 개선한다.
- 교훈
이 파이프라인은 주로 데이터 양을 다루지만, 어긋난 타임스탬프도 카디널리티 변화만큼 파이프라인을 흔들 수 있었다. 이상한 지표를 바로 설명하지 못했다고 치워 두면 안 된다. 이번에도 원인으로 이끈 것은 처음에 무시한 insert 크기 감소였다. 중앙값과 평균은 각자 쓸모가 있고, 이번에는 평균이 실마리였다. 파티션이 너무 적으면 파트가 커지고 mutation 이 느려지며 TTL 이 너무 비싸지거나 아예 동작하지 않는다. 반대로 너무 많으면 열 스캔과 집계 쿼리가 느려지고 Keeper 가 과부하된다. Keeper 작업은 파트 수에 따라 선형보다 훨씬 빠르게 늘었다.
- 증상
2023년 11월 6일 10:52 AM PST 에 업그레이드 스크립트가 scylla-authentication 클러스터의 존 c 연결을 모두 비우자, 2xx 응답 비율로 재는 Discord 의 가용성이 곧바로 약 25% 로 떨어졌다. 사용자는 접속, 로그인, 메시지 읽기와 보내기를 거의 할 수 없었다. 첫 알림은 4분쯤 뒤인 10:56 AM 에 울렸다.
- 촉발
2023년 11월 6일 운영체제 업그레이드 절차가 scylla-authentication 클러스터의 존 b 를 마친 뒤, 10:52 AM 에 스크립트가 존 c 의 연결을 모두 비우고 업그레이드를 시작했다. 존 b 에는 디스크 성능이 떨어진 노드가 있었다.
- 원인
- 구성 요소
- 기여 요인
- 감지
첫 알림이 장애 시작 4분쯤 뒤인 10:56 AM 에 울렸지만, 팀은 그 전에 이미 사고 대응 통화를 열고 조사하고 있었다. 하위 서비스별 소요 시간 그래프가 인증 서비스를 가리켰고, 잠시 뒤 인증 알림이 울렸다.
- 조치
- 11:05 AM 에 인증 클러스터의 부하를 덜려고 입력 중 표시 이벤트와 메시지 읽음 표시를 껐다.
- RAID 재구축이 끝나기를 기다려 11:41 AM 에 존 c 의 두 노드를 다시 올렸다.
- 과부하였던 존 b 의 두 노드를 한 대씩 재시작했다.
- 후속 조치
- 사고 직후 scylla-authentication 클러스터를 두 배로 늘려 용량을 더했다.
- scylla-authentication-b-2 를 성능이 떨어지지 않은 새 디스크로 다시 만들었다.
- 전체 지연에는 드러나지 않을 만큼 약하지만 서비스 신뢰성에 위험이 될 수 있는 디스크 성능 저하를 찾아내는 방법을 만든다.
- Scylla 클러스터의 컨트롤 플레인을 더 자동화하고 업그레이드 작업을 그곳으로 옮겨, 캐시 적중률 같은 클러스터 분석을 업그레이드 절차에 넣는다.
- 복제 계수를 늘리거나 다른 리전에 핫 스탠바이 클러스터를 두는 방안을 검토해, 이 작고 중요한 클러스터의 이중화를 늘린다.
- 교훈
클러스터는 존 하나를 잃어도 견디게 설계했지만, 존 하나가 내려간 상태에서 다른 존의 노드 하나 성능이 떨어진 것만으로 이 정도 장애가 났다는 것은 클러스터의 용량이 부족했다는 뜻이다. 노드 재시작 전에 캐시 적중률이 일정 수준이 돼야 하는 것도 용량 부족의 신호다. 업그레이드 전 존 중단 시험은 계속 진행해도 안전하다는 잘못된 확신을 줬다. 이 작고 중요한 클러스터는 훨씬 큰 다른 클러스터들과 다르게 운영해야 한다.
- 증상
2019년 2월 4일 05:35 UTC 부터 Mandrill 이 대기열에 쌓인 메일의 80% 만 보냈다. 첫 예외는 일요일 밤에 로그에 남았지만 다른 시스템의 관계없는 예외에 묻혀 중앙 오류 보고에서 눈에 띄지 않았다.
- 촉발
Mandrill 의 키 해시 알고리즘이 shard4 에 쓰기를 더 많이 몰아 이 샤드의 autovacuum 이 밀렸거나 실패했고, 2019년 2월 4일 05:35 UTC 에 XID 가 상한에 닿아 데이터베이스가 안전 종료 모드로 들어갔다.
- 원인
- 구성 요소
- 기여 요인
- 감지
첫 예외는 일요일 밤에 로그에 남았지만 다른 시스템의 관계없는 예외에 묻혀 중앙 오류 보고에서 늦게 발견됐다. 11:58 UTC 에 Mandrill 엔지니어가 조사를 시작했고, shard4 의 부하 급증을 쫓다가 12:56 UTC 에 랩어라운드를 찾았다.
- 조치
- 14:16 UTC 에 shard4 를 단일 사용자 모드로 띄우고 VACUUM 을 시작했다.
- VACUUM 이 며칠 걸릴 것으로 보여 설정을 바꿔 속도를 높인 뒤 다시 시작했다.
- VACUUM 이 도는 동안 데이터베이스 덤프와 복원을 시작했고, 속도를 높이려고 TB 단위인 Search 와 Url 테이블을 뺐다.
- 실패한 작업과 로그로 디스크가 모자라자 Mandrill 앱 서버들의 스토리지 볼륨을 교체했다.
- shard4 에 있던 작업 대기열 테이블을 살아 있는 다른 샤드로 옮겨 작업이 처리되게 하려 했다.
- 잠긴 데이터베이스에서 테이블을 비우면 그 XID 가 풀린다는 것을 확인한 뒤 2월 5일 19:12 UTC 에 Search 와 Url 테이블을 비웠고, VACUUM 이 약 한 시간 뒤에 끝났다.
- 21:36 UTC 에 밀린 메일 발송을 시작했다.
- 22:40 UTC 에 XID 랩어라운드 알림을 새로 걸었다.
- 교훈
Mailchimp 는 대응을 늦춘 요인으로 다섯 가지를 들었다. Mandrill 시스템과 모니터링을 알고 접근할 수 있는 사람이 몇 명뿐이었다. Mandrill 의 로그 기록은 로컬에 쓸 수 있는 디스크에 기댔다. 잘못된 API 요청 로그와 실제 애플리케이션 오류를 구분하기 어려웠다. 작업 상태가 잘 보이지 않았다. 디스크 공간 문제로 원인 분석을 돕는 부분 배포가 위험했다. 잘된 점으로는 인시던트 지휘관을 중심으로 한 긴밀한 조율, 3시간 교대와 인수인계, 기록 담당과 기술 연락 담당 같은 역할 지정, 주기적인 요약과 결정 목록을 들었다. 화상 회의로 다시 모여 상황을 따져 본 것이 테이블을 비우는 해법으로 이어졌다. 대기 메일을 48시간 뒤에 지우는 기본 동작이 다가오자 더 과감한 방법을 검토하게 됐다. Mandrill 이 클라우드에서 돌아 스토리지를 빨리 늘릴 수 있었던 것은 운이었다. 지울 수 있는 데이터가 있었고 그 가운데 VACUUM 을 붙잡던 가장 큰 테이블이 있었던 것도 운이었다.
- 증상
6월 3일 PagerDuty 알림 파이프라인의 성능이 떨어져 일부 알림이 늦게 갔다. 통합 API 로 보낸 이벤트의 약 3% 를 받지 못했고, 1% 에 못 미치는 일부 알림이 늦게 전달됐다.
- 촉발
6월 3일 Cassandra 클러스터의 노드 하나에서 repair 작업이 평소대로 시작됐고, 그때 걸린 높은 부하와 겹쳤다. 6월 4일에는 팀이 전날 미룬 repair 작업을 손으로 다시 시작했다.
- 원인
- 구성 요소
- 기여 요인
- 조치
- 6월 3일 Cassandra 클러스터의 부하를 줄였다.
- 6월 3일 부하를 줄이면서 repair 작업을 멈췄다.
- 클러스터를 안정시키려고 일부 노드 사이의 통신을 끊었고, 그 뒤 정상으로 돌아왔다.
- 6월 4일 알림 파이프라인에서 처리 중이던 데이터를 모두 지웠고, Cassandra 가 바로 회복했다.
- 새로 비운 상태와 데이터를 맞추도록 일부 하위 시스템을 수동으로 손봤다.
- 후속 조치
- 기존 Cassandra 노드를 더 크고 빠른 서버로 수직 확장한다. 6월 4일 이후 이 작업은 이미 끝냈다.
- Cassandra 클러스터를 여러 개로 나누고 작업량을 그 클러스터들에 나눠 싣는다. 부하와 사용 방식에 따라 클러스터를 나누는 작업이 진행 중이다.
- 시스템 부하 기준을 정해 그 기준에 닿으면 기존 Cassandra 클러스터를 미리 수평 확장한다.
- 기존 클러스터와 새 클러스터를 더 최근 버전의 Cassandra 로 업그레이드한다.
- 높은 부하에서도 Cassandra 를 통제할 수 있도록 로드 셰딩 기법을 더 넣는다.
- Cassandra 전문 인력을 사내에 더 둔다.
- 교훈
PagerDuty 는 Cassandra 클러스터의 규모가 모자랐고, 부하와 사용 방식이 서로 다른 너무 많은 서비스가 한 클러스터를 나눠 쓰고 있었다고 밝혔다. 비슷한 문제를 보고 개선을 계획했지만 효율을 기준으로 버전 업그레이드를 먼저 하려 했고, 확장을 먼저 했어야 했다고 적었다.
이 5건에서 가장 많이 나오는 구성 요소: 데이터베이스, PostgreSQL vacuum. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.
원인별1
용량 한계5건
- 기여 요인
IL-0553워크플로 조율 서비스의 데이터베이스에서 트랜잭션 로그 볼륨이 차서 CircleCI 파이프라인과 잡이 멈추고 몇 시간 동안 늦게 시작했다CircleCI2026IL-0288CDN77 의 ClickHouse 데이터 파이프라인에서 이중화된 인스턴스 세 곳의 ZooKeeperWait 가 수천 초로 치솟아 복제가 한 시간 넘게 느려졌다CDN772026IL-0270인증용 ScyllaDB 클러스터가 과부하로 조회를 처리하지 못해 Discord 에서 약 50분 동안 접속과 로그인이 되지 않았다Discord2023IL-0211Mandrill 의 PostgreSQL 샤드 하나가 트랜잭션 ID 랩어라운드를 막으려고 쓰기를 멈춰 약 40시간 동안 메일 발송이 줄었다Mailchimp2019IL-0383PagerDuty 알림 파이프라인이 이틀 연속 장애를 겪어 이벤트를 받지 못하고 알림이 늦거나 가지 않았다PagerDuty2014