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 레코드를 넣고 가져오는 호출의 오류 알람이 울리기 시작했고, 팀이 로그를 보기 시작했다.
조치
- 조심하려고 다른 오류를 조사하면서 새로 더한 프런트엔드 용량을 빼기 시작했다.
- 재시작을 빠르게 하려고, 프런트엔드 서버가 시작할 때 이웃 프런트엔드 서버 대신 정본 메타데이터 저장소에서 바로 데이터를 받도록 설정을 넣기 시작했다.
- 10:07 AM PST 부터 프런트엔드 서버를 다시 올리며 시간당 수백 대씩 천천히 트래픽을 더했다.
- Cognito 팀은 장애 초기에 용량을 더해 Kinesis 호출을 버퍼링할 여유를 늘렸다.
- 10:15 AM PST 에 Cognito 의 Kinesis 의존을 줄이는 변경을 배포하기 시작했고, 오류율이 내려가기 시작했다.
- 10:36 AM PST 에 엔지니어들이 Lambda 함수 호출 호스트의 메모리 경합을 줄이는 조치를 해서 호출 오류가 풀렸다.
- 의존이 적은 예비 도구로 Service Health Dashboard 에 게시하고, Personal Health Dashboard 로 영향받은 고객에게 직접 알리고, Service Health Dashboard 에 전역 배너 요약을 올려 고객에게 상황을 알렸다.
후속 조치
- CPU 와 메모리가 더 큰 서버로 옮겨 서버 수를 줄이고, 서버마다 서버군 안에서 통신하는 데 필요한 스레드 수를 줄인다.
- 서비스의 스레드 사용량에 세밀한 알람을 더한다.
- 운영체제 설정의 스레드 수 한도를 올리는 시험을 마친다.
- 프런트엔드 서버군의 콜드 스타트 시간을 크게 줄이는 변경을 한다.
- 프런트엔드 서버 캐시를 전용 서버군으로 옮긴다.
- CloudWatch 같은 큰 AWS 서비스 몇 개를 따로 나눈 프런트엔드 서버군으로 옮긴다.
- 백엔드에서 한 것처럼 프런트엔드 서버군의 셀 단위 분리를 크게 앞당긴다.
- Cognito 웹 서버가 Kinesis API 오류를 겪어도 버퍼를 다 쓰지 않고 버티도록 고쳤다.
- CloudWatch 로컬 지표 데이터 저장소에 지표 데이터 3시간 치를 보관해, CloudWatch 사용자와 AutoScaling 같은 서비스가 최근 지표를 바로 읽게 한다. US-EAST-1 에는 적용을 마쳤고 앞으로 몇 주 동안 전 세계에 배포한다.
- 지원 엔지니어가 Service Health Dashboard 예비 게시 도구를 정기적으로 훈련받도록 지원 교육을 바꿨다.
교훈
프런트엔드 서버마다 유지할 스레드 수는 서버군의 서버 수에 비례하므로, 서버 수를 줄이면 스레드 수에 큰 여유가 생긴다. AWS 에 따르면 셀 단위 분리는 서비스 안에서 장애의 영향을 가두고, shard-map 캐시 같은 구성 요소가 이미 시험하고 운영해 본 범위 안에서 돌게 하는 방법이다. 프런트엔드 서버군의 셀 단위 분리는 진행 중이었지만 일이 커서 아직 끝나지 않았다. AWS 는 이 작업이 끝나면 앞으로 드러날 모르는 확장 한도에도 더 잘 대비할 수 있다고 봤다.
출처
- https://aws.amazon.com/message/11201/ · official-status · 보관본
관련 사례
IL-0288CDN77 의 ClickHouse 데이터 파이프라인에서 이중화된 인스턴스 세 곳의 ZooKeeperWait 가 수천 초로 치솟아 복제가 한 시간 넘게 느려졌다CDN77 · 2026같은 원인 · 공통 텔레메트리 에이전트
IL-0390PostHog US Cloud 의 Persons Postgres 데이터베이스 쓰기가 크게 느려져 이벤트와 persons 수집이 최대 2일 지연됐다PostHog · 2025같은 원인 · 공통 메시지 브로커
같은 원인 · 공통 메시지 브로커
IL-0042OpenSearch 디스크가 가득 찬 동안 fluent-bit 가 로그를 처리하지 못해 Elasticsearch 와 OpenSearch 에 애플리케이션 로그가 들어오지 않았다.UK Ministry of Justice · 2024같은 원인 · 공통 텔레메트리 에이전트
IL-0110Grafana Agent 파드가 메모리를 많이 쓰던 노드에 Hangfire 파드가 함께 올라가 시스템 OOM 으로 CrashLoopBackOff 를 반복했고, 노드가 응답을 멈추고 NotReady 가 됐다.DFDS · 2024같은 원인 · 공통 텔레메트리 에이전트
같은 원인 · 공통 텔레메트리 에이전트
IL-0194kube-apiserver 재시작 뒤 Vector DaemonSet 의 파드 list 요청이 한꺼번에 몰려 etcd 메모리가 세 배 가까이 늘고 마스터 노드가 연쇄적으로 재시작했다.Palark · 2023같은 원인 · 공통 텔레메트리 에이전트
IL-0026메모리 제한이 없는 fluentd-sumologic 파드가 메모리를 다 써서 운영 쿠버네티스 노드 두 대에 이틀 연속 SystemOOM 이 났다Blue Matador · 2019같은 원인 · 공통 텔레메트리 에이전트
IL-0075클러스터가 EC2 인스턴스 약 290대로 커지자 노드마다 도는 Datadog 에이전트가 쿠버네티스 API 를 폴링하면서 API 서버가 CPU 와 메모리를 다 써 쿠버네티스 컨트롤 플레인을 쓸 수 없게 됐다.Civis Analytics · 2019같은 원인 · 공통 텔레메트리 에이전트
IL-0275Kafka 브로커들이 네트워크 한계에 닿아 줄줄이 쓰러지면서 Parse.ly 의 데이터 처리가 멈추고 대시보드에 몇 시간 동안 새 데이터가 나오지 않았다Parse.ly · 2015같은 원인 · 공통 메시지 브로커
내 클러스터에도 있는지 확인하기
AI 도구와 스크립트용
- 이 사례의 JSON: https://incidentlib-api.benchlet.com/cases/IL-0384
- 가장 비슷한 사례들: https://incidentlib-api.benchlet.com/cases/IL-0384/similar
- MCP 서버(Streamable HTTP, 키 없음):
https://incidentlib-mcp.benchlet.com/mcp
API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.