Incident Library

IL-0384 Amazon Web Services · 2020-11-25awsdatabaseobservability

US-EAST-1 의 Amazon Kinesis Data Streams 에서 레코드 읽기와 쓰기가 하루 대부분 실패했다

Amazon Kinesis 는 스트리밍 데이터를 실시간으로 처리하는 서비스이고, 고객이 직접 쓸 뿐 아니라 여러 AWS 서비스가 쓴다. 스트림은 많은 백엔드 셀 클러스터가 처리하고, 프런트엔드 서버군이 샤딩으로 스트림을 백엔드에 나눈다. 프런트엔드는 인증, 스로틀링, 알맞은 스트림 샤드로 요청을 보내는 일을 맡는다. 프런트엔드 서버마다 백엔드 클러스터의 구성원 정보와 샤드 소유 정보를 담은 shard-map 이라는 캐시를 둔다. 서버는 이 정보를 구성원 정보를 내주는 마이크로서비스, DynamoDB 의 설정 정보, 다른 프런트엔드 서버가 보내는 메시지에서 얻는다. 다른 서버의 메시지를 받으려고 프런트엔드 서버는 서버군의 다른 서버마다 운영체제 스레드를 하나씩 만든다. 그래서 서버마다 유지할 스레드 수는 서버군의 서버 수에 비례한다.

2020년 11월 25일 2:44 AM PST 부터 3:47 AM PST 까지 US-EAST-1 의 프런트엔드 서버군에 비교적 작은 용량을 더했다. 기존 서버가 새 서버를 알아채는 데 최대 한 시간이 걸린다. 5:15 AM PST 에 Kinesis 레코드를 넣고 가져오는 호출의 오류 알람이 울리기 시작했다. 오류가 여러 가지여서 진단이 늦어졌고, 팀은 조심하려고 새 용량을 빼기 시작했다. 7:51 AM PST 에 원인 후보를 두어 개로 좁혔고, 어느 후보든 프런트엔드 서버군 전체를 재시작해야 한다고 판단했다. 프런트엔드 서버에서는 shard-map 을 채우는 자원과 들어오는 요청을 처리하는 자원이 서로 다툰다. 그래서 서버를 너무 빨리 올리면 요청을 처리할 자원이 모자라 오류와 지연이 늘고, 느린 서버가 비정상으로 판정돼 서버군에서 빠질 수 있었다. 팀은 조사와 함께, 서버가 시작할 때 이웃 프런트엔드 서버 대신 정본 메타데이터 저장소에서 바로 데이터를 받도록 설정을 넣기 시작했다.

9:39 AM PST 에 근본 원인을 확인했다. 새 용량 때문에 서버군의 모든 서버가 운영체제 설정이 허용하는 최대 스레드 수를 넘었다. 그래서 캐시를 다 만들지 못했고, 프런트엔드 서버는 쓸모없는 shard-map 을 들고 백엔드 클러스터로 요청을 보내지 못했다. 팀은 더 시험하지 않은 채 운영체제 한도를 올리지는 않기로 했다. 촉발 요인이 된 추가 용량을 막 다 뺀 참이어서 스레드 수가 더는 한도를 넘지 않는다고 보고 재시작을 진행했다. 10:07 AM PST 에 첫 서버 묶음이 Kinesis 트래픽을 받기 시작했다. 프런트엔드 서버군은 서버 수천 대로 이루어져 있는데, 서버는 시간당 수백 대씩만 다시 더할 수 있었다. 정오부터 오류율이 꾸준히 내려갔고, Kinesis 는 10:23 PM PST 에 완전히 정상으로 돌아왔다.

Kinesis 를 쓰는 다른 서비스도 실패했다. Cognito 는 API 접근 패턴을 Kinesis Data Streams 로 보내면서 데이터를 로컬에 버퍼링한다. 오래 끈 Kinesis 장애가 이 버퍼링 코드에 숨어 있던 버그를 건드려, Cognito 웹 서버가 밀린 버퍼에서 막혔다. 그래서 Cognito User Pools 와 Identity Pools 의 API 실패와 지연이 늘었다. Cognito 팀은 10:15 AM PST 에 Kinesis 의존을 줄이는 변경을 배포하기 시작했고, Cognito 는 2:18 PM PST 에 정상으로 돌아왔다. CloudWatch 는 5:15 AM PST 부터 PutMetricData 와 PutLogEvents API 의 오류와 지연이 늘어 대부분의 지표를 처리하지 못했고, 알람이 INSUFFICIENT_DATA 상태로 바뀌었다. CloudWatch 의 지표와 알람은 10:31 PM PST 에 완전히 회복했다. CloudWatch 지표에 기대는 반응형 AutoScaling 정책은 늦게 동작했다. Lambda 는 호출마다 CloudWatch 에 지표를 보내야 하는데, 지표 버퍼가 커지면서 호스트 메모리 경합이 생겨 6:15 AM PST 부터 호출 오류가 늘었다. 이 오류는 10:36 AM PST 에 풀렸다. CloudWatch Events 와 EventBridge 는 5:15 AM PST 부터 API 오류와 이벤트 처리 지연을 겪었다. EventBridge 로 내부 작업 흐름을 돌리는 ECS 와 EKS 에서는 새 클러스터 만들기와 태스크 정리가 영향을 받았고, 기존 클러스터 확장이 늦어졌다. 이 문제들은 4:15 PM PST 까지 대부분 풀렸다. 장애 초기에는 Service Health Dashboard 갱신 도구가 Cognito 를 써서 대시보드를 갱신하지 못했다. 의존이 적은 예비 도구는 동작했지만 지원 담당자에게 익숙하지 않아 게시가 늦었다.

심각도
–
영향 범위
Kinesis Data Streams in US-EAST-1 and AWS services that use it: Cognito User Pools and Identity Pools, CloudWatch metrics, logs and alarms, reactive AutoScaling, Lambda invocations, CloudWatch Events and EventBridge, and ECS and EKS cluster provisioning, scaling and task de-provisioning; Service Health Dashboard updates were delayed
영향 사용자
–
지역
US-EAST-1 (Northern Virginia)
감지까지
–
복구까지
17h 8m

증상

2020년 11월 25일 5:15 AM PST 에 Kinesis 레코드를 넣고 가져오는 호출의 오류 알람이 울리기 시작했다. Kinesis 를 쓰는 CloudWatch, CloudWatch Events, EventBridge 도 같은 시각부터 오류와 지연을 보였다.

오류는 한 종류가 아니었다. 기존 프런트엔드 서버와 새로 더한 서버가 하는 여러 호출에서 단계를 가리지 않고 오류가 났다. 그래서 부작용과 근본 원인을 가려내기 어려웠다.

팀은 새로 더한 용량을 의심했다. 그러나 새 용량과 상관없어 보이고 용량을 빼도 남을 것 같은 오류가 많았다. 그래도 조심하려고 다른 오류를 조사하면서 새 용량을 빼기 시작했다.

7:51 AM PST 에 근본 원인 후보를 두어 개로 좁혔다. 가장 유력한 후보는 메모리 압박을 일으키는 듯한 문제였지만, 9:39 AM PST 에 확인한 원인은 메모리 압박이 아니었다.

CloudWatch 에서는 PutMetricData 와 PutLogEvents API 의 오류율과 지연이 올라갔고, 알람이 INSUFFICIENT_DATA 상태로 바뀌었다. Cognito User Pools 와 Identity Pools 에서는 API 실패와 지연이 늘어 외부 사용자가 인증하거나 임시 AWS 자격 증명을 받지 못했다.

장애 초기에는 Service Health Dashboard 를 갱신할 수 없었다. 갱신에 쓰는 도구가 Cognito 를 쓰고 있었기 때문이다.

증상 오류율 상승지연 시간 증가모니터링 중단

원인

촉발
2:44 AM PST 부터 3:47 AM PST 까지 Kinesis 프런트엔드 서버군에 비교적 작은 용량을 더했다. AWS 는 이것이 촉발 요인이었지만 근본 원인은 아니었다고 밝혔다.

감지

5:15 AM PST 에 Kinesis 레코드를 넣고 가져오는 호출의 오류 알람이 울리기 시작했고, 팀이 로그를 보기 시작했다.

조치

후속 조치

교훈

프런트엔드 서버마다 유지할 스레드 수는 서버군의 서버 수에 비례하므로, 서버 수를 줄이면 스레드 수에 큰 여유가 생긴다. AWS 에 따르면 셀 단위 분리는 서비스 안에서 장애의 영향을 가두고, shard-map 캐시 같은 구성 요소가 이미 시험하고 운영해 본 범위 안에서 돌게 하는 방법이다. 프런트엔드 서버군의 셀 단위 분리는 진행 중이었지만 일이 커서 아직 끝나지 않았다. AWS 는 이 작업이 끝나면 앞으로 드러날 모르는 확장 한도에도 더 잘 대비할 수 있다고 봤다.

출처

관련 사례

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

kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이 사례와 같은 상태를 점검합니다. 이 사례의 구성 요소: 메시지 브로커, 서버리스 함수 플랫폼, 텔레메트리 에이전트. 점검 항목의 근거는 이 사례 같은 공개 보고서입니다.

AI 도구와 스크립트용

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