그래프
사례2건
2건 중 1~2번째
- 증상
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 을 붙잡던 가장 큰 테이블이 있었던 것도 운이었다.
- 증상
2013년 7월 18일 2:42 AM PDT 에 모니터링 시스템이 결제용 Redis 클러스터의 장애를 당번 엔지니어에게 알렸다. redis-master 호스트의 부하가 극도로 높았고, redis-master 에 기대는 서비스들이 실패하고 있었다.
- 촉발
7월 18일 1:35 AM PDT 에 네트워크 연결이 끊겨 결제용 redis-slave 전부가 동시에 redis-master 와 끊겼고, 다시 붙으면서 한꺼번에 전체 동기화를 요청했다. 부하가 높아진 redis-master 를 당번 엔지니어가 재시작했다.
- 원인
- 구성 요소
- 기여 요인
- 감지
2:42 AM PDT 에 모니터링 시스템이 Redis 클러스터 장애를 당번 엔지니어링 팀에 알렸다. 잘못된 결제는 3:28 AM PDT 에 결제 시스템 모니터링이 이상 동작을 보고해 알았고, 12:36 PM PDT 에는 모니터링이 같은 이상의 재발을 찾았다.
- 조치
- 2:42 AM PDT 에 당번 엔지니어가 높은 부하를 해결하려고 redis-master 를 재시작했다.
- 4:10 AM PDT 에 신용카드 결제가 더 일어나지 않게 결제 시스템을 내렸다.
- 6:24 AM PDT 에 정지된 계정을 모두 되살렸고, 결제 시스템은 원인을 조사하는 동안 꺼 둔 채로 뒀다.
- 별도 관계형 데이터 저장소에 따로 적어 둔 잔액 기록으로 redis-master 에서 잃은 계정 잔액을 복원했다.
- 12:36 PM PDT 에 같은 이상이 다시 나타나자 결제 시스템을 다시 내리고 정지된 계정을 바로 되살렸다.
- 2:57 PM PDT 부터 잘못된 신용카드 결제를 환불해 7월 19일 3:00 PM PDT 에 모두 마쳤다.
- 7월 19일 3:30 PM PDT 에 영향받은 모든 계정에 최근 30일 Twilio 사용액의 10% 를 크레딧으로 줬다.
- 장애를 일으킨 원래 Redis 클러스터를 교체했고, redis-master 의 잘못된 설정을 찾아 고쳤다.
- 7월 19일 7:10 PM PDT 부터 고객 계정 묶음마다 결제 시스템을 차례로 켰다.
- 후속 조치
- redis-master 의 Redis 재시작을 막고, 앞으로 redis-master 복구는 slave 를 승격해 처리한다.
- 결제 잔액이 없거나 쓸 수 없으면 계정을 정지하거나 신용카드를 결제하지 않도록 안전장치를 넣는다.
- 결제 시스템이 잔액을 따로 적어 두는 데이터베이스와 실시간으로 대조하게 바꾼다.
- 교훈
Twilio 는 현재 잔액 데이터와 잔액을 갱신하는 능력을 동시에 잃자 자동 충전 시스템이 위험한 방향으로 실패했다고 봤다. 잔액이 없거나 쓸 수 없을 때 자동 충전 시스템은 계정을 정지하지 않고 카드를 결제하지 않는 쪽으로 멈춰야 했다.
이 2건에서 가장 많이 나오는 구성 요소: PostgreSQL vacuum, 인메모리 캐시. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.