Incident Library

IL-0215 Twilio · 2013-07-18database

Twilio 결제 시스템의 Redis 가 잔액 데이터를 잃고 읽기 전용이 되어 자동 충전 고객의 신용카드가 반복 결제됐다

Twilio 결제 시스템은 현재 계정 잔액을 메모리 기반 Redis 클러스터에 둔다. 이 클러스터는 master 하나와 여러 데이터센터에 나눠 둔 slave 들로 이루어진다. 2013년 7월 18일 1:35 AM PDT 에 네트워크 연결이 끊겨 모든 redis-slave 가 동시에 master 와 끊겼다가 다시 붙으며 전체 동기화를 요청했고, master 는 극심한 부하에 빠졌다. 2:39 AM PDT 에 redis-master 에 기대는 서비스들이 실패하기 시작했고, 2:42 AM PDT 에 당번 엔지니어는 부하를 보고 redis-master 를 재시작했다.

재시작한 redis-master 는 잘못된 설정 파일을 읽어 바이너리 스냅샷 대신 없는 AOF 파일로 복구하려다 실패했고, 모든 잔액 데이터를 잃었다. 잘못된 설정은 redis-master 를 자기 자신의 slave 로 띄워 읽기 전용으로 만들었다. 잔액이 0 이고 갱신할 수 없으니 자동 충전이 켜진 계정은 과금 거래가 생길 때마다 신용카드 충전을 시도했고, 같은 카드가 반복해서 결제됐다. 반복 결제로 비활성화된 카드에 충전을 시도한 계정은 정지됐다.

3:28 AM PDT 에 모니터링이 이상을 찾아 고객의 1.1% 가 영향을 받은 것을 알았고, 4:10 AM PDT 에 결제 시스템을 내렸다. 6:24 AM PDT 에 정지된 계정을 모두 되살렸고, 별도 관계형 데이터 저장소에 따로 적어 둔 잔액 기록으로 잔액을 복원했다. 11:58 AM PDT 에 결제 시스템을 다시 켰지만 12:36 PM PDT 에 같은 이상이 다시 나타나 고객 0.3% 가 더 영향을 받았고, 다시 내렸다. 2:57 PM PDT 부터 잘못된 결제를 환불해 7월 19일 3:00 PM PDT 에 마쳤고, 영향받은 계정에 최근 30일 사용액의 10% 를 크레딧으로 줬다. 문제를 일으킨 Redis 클러스터는 교체했고 잘못된 설정을 고쳤다. 7:10 PM PDT 부터 결제 시스템을 계정 묶음마다 차례로 켜 8:14 PM PDT 에 모든 고객에게 켰고, 9:15 PM PDT 에 모든 시스템이 복구됐다. 영향받은 고객은 모두 1.4% 였다.

심각도
–
영향 범위
Twilio billing: payments did not update balances, auto-recharge charged cards repeatedly and some accounts were suspended; usage reports for all customers were delayed in reflecting prices while billing was offline; voice and SMS were not affected
영향 사용자
1.4% of Twilio customers (1.1% in the first wave, 0.3% in the recurrence)
지역
–
감지까지
1h 7m
복구까지
43h 40m

증상

2013년 7월 18일 2:42 AM PDT 에 모니터링 시스템이 결제용 Redis 클러스터의 장애를 당번 엔지니어에게 알렸다. redis-master 호스트의 부하가 극도로 높았고, redis-master 에 기대는 서비스들이 실패하고 있었다.

1:35 AM PDT 에 네트워크 연결이 끊기며 모든 redis-slave 가 동시에 master 와 끊겼다. redis-slave 들이 한꺼번에 다시 붙어 전체 동기화를 요청하자 master 의 성능이 떨어지고 redis-slave 에서 redis-master 로 가는 요청이 타임아웃됐다.

당번 엔지니어는 극심한 부하를 보고 redis-master 의 redis 프로세스를 재시작해야 한다고 잘못 판단했다. 재시작한 redis-master 는 모든 잔액 데이터를 잃었고 읽기 전용 상태가 되어 잔액을 갱신할 수 없었다.

3:28 AM PDT 에 결제 시스템 모니터링이 이상 동작을 보고했다. 잘못된 신용카드 결제와 일부 계정 정지가 일어났고, Twilio 전체 고객의 1.1% 가 영향을 받았다. 고객이 신용카드로 결제해도 계정 잔액에 반영되지 않았다. 잔액이 모두 0 이라 SMS 한 건이나 전화 한 통처럼 1센트짜리 사용도 자동 충전을 일으켰다. 충전해도 잔액이 갱신되지 않아 같은 카드에 결제가 거듭 시도됐다. 반복 결제로 비활성화된 카드에 충전을 시도한 일부 계정은 정지됐다.

결제 시스템이 꺼져 있는 동안 모든 고객의 사용량 보고서에 과금 항목의 가격이 늦게 반영됐다. 음성과 SMS 서비스는 영향을 받지 않았지만 그동안의 통화와 메시지 가격은 계산되지 않았다.

11:58 AM PDT 에 결제 시스템을 다시 켜자 12:36 PM PDT 에 모니터링이 같은 이상을 다시 찾았고, 고객의 0.3% 가 더 영향을 받았다. 결제 시스템은 다시 내려졌다.

증상 데이터베이스 과부하데이터 유실쓰기 거부

원인

촉발
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 에는 모니터링이 같은 이상의 재발을 찾았다.

조치

후속 조치

교훈

Twilio 는 현재 잔액 데이터와 잔액을 갱신하는 능력을 동시에 잃자 자동 충전 시스템이 위험한 방향으로 실패했다고 봤다. 잔액이 없거나 쓸 수 없을 때 자동 충전 시스템은 계정을 정지하지 않고 카드를 결제하지 않는 쪽으로 멈춰야 했다.

출처

관련 사례

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

kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이 사례와 같은 상태를 점검합니다. 이 사례의 구성 요소: 인메모리 캐시, 데이터베이스 복제. 점검 항목의 근거는 이 사례 같은 공개 보고서입니다.

AI 도구와 스크립트용

API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.