{"id":"IL-0384","org":"Amazon Web Services","date":"2020-11-25","docs":[],"title":{"en":"Amazon Kinesis front-end servers in US-EAST-1 could not route requests, so Kinesis and services built on it failed","ko":"US-EAST-1 의 Amazon Kinesis Data Streams 에서 레코드 읽기와 쓰기가 하루 대부분 실패했다"},"domain":["aws","database","observability"],"impact":{"scope":"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","users":"unknown","region":"US-EAST-1 (Northern Virginia)"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"In the Kinesis front-end, the number of threads each server keeps grows directly with the number of servers in the fleet, so adding servers can push every server past an operating system limit at the same time. AWS sees cellularization of the front-end, already done for the back-end, as the way to keep the shard-map cache within a tested and operated range and to guard against unknown scaling limits.","ko":"프런트엔드 서버마다 유지할 스레드 수는 서버군의 서버 수에 비례하므로, 서버 수를 줄이면 스레드 수에 큰 여유가 생긴다. AWS 에 따르면 셀 단위 분리는 서비스 안에서 장애의 영향을 가두고, shard-map 캐시 같은 구성 요소가 이미 시험하고 운영해 본 범위 안에서 돌게 하는 방법이다. 프런트엔드 서버군의 셀 단위 분리는 진행 중이었지만 일이 커서 아직 끝나지 않았다. AWS 는 이 작업이 끝나면 앞으로 드러날 모르는 확장 한도에도 더 잘 대비할 수 있다고 봤다."},"related":[],"sources":[{"url":"https://aws.amazon.com/message/11201/","kind":"official-status","archived":"https://web.archive.org/web/20260902131800/https://aws.amazon.com/message/11201/"}],"summary":{"en":"Kinesis Data Streams spreads streams over many back-end cell-clusters through sharding owned by a front-end fleet of servers, which handles authentication, throttling and routing of requests to the right shards. Each front-end server keeps a cache called the shard-map with membership and shard ownership of the back-end clusters, built from calls to a membership microservice, configuration in DynamoDB and messages from the other front-end servers. For those messages each front-end server creates an operating system thread for every other server in the fleet, and existing servers take up to an hour to learn about new ones. Between 2:44 and 3:47 AM PST on 25 November 2020 AWS added a relatively small amount of capacity to the front-end fleet. As the servers learned of the new members, every server in the fleet went over the maximum number of threads allowed by an operating system configuration, shard-map construction could not finish, and the front-end servers were left with useless shard-maps that could not route requests to the back-end clusters. The first alarms fired at 5:15 AM PST.\n\nAWS removed the new capacity as a precaution and by 7:51 AM PST saw that every likely fix meant changing the configuration of every front-end server and restarting the whole fleet. That restart had to be slow: building the shard-map competes for resources with serving requests, so servers brought back too fast would be slow, could be judged unhealthy and removed, and would set recovery back. In parallel AWS added a configuration so that front-end servers load their data at bootstrap from the authoritative metadata store instead of from neighbouring front-end servers. At 9:39 AM PST AWS confirmed the thread limit as the cause. Rather than raise the operating system limit without more testing, AWS relied on the completed capacity removal to keep the thread count under the limit and went ahead with the restart. The first servers took traffic at 10:07 AM PST, the fleet of many thousands of servers could only be brought back a few hundred per hour, errors fell steadily from noon, and Kinesis was fully back to normal at 10:23 PM PST.\n\nServices that use Kinesis failed with it. In Cognito, the long Kinesis outage set off a latent bug in local buffering that made the Cognito webservers block on backlogged Kinesis buffers; extra Cognito capacity helped at first, errors rose sharply by 7:01 AM PST, a change that reduced Cognito's dependency on Kinesis began deploying at 10:15 AM, and Cognito was normal by 2:18 PM PST. CloudWatch, which processes metrics and logs through Kinesis, could not process most metrics from 5:15 AM, began to recover at 5:47 PM and fully recovered by 10:31 PM PST, with backfilling over the following hours; reactive AutoScaling policies were delayed until 5:47 PM PST. Lambda invocations must publish metrics to CloudWatch, and the local buffers of the Lambda metric agents grew until they caused memory contention on the hosts that run invocations, raising errors from 6:15 AM until engineers mitigated it at 10:36 AM PST. CloudWatch Events and EventBridge had API errors and delayed events from 5:15 AM, which affected ECS and EKS cluster provisioning, scaling and task de-provisioning until most issues were resolved by 4:15 PM PST. The Service Health Dashboard posting tool depends on Cognito, so AWS used the slower backup tool, the Personal Health Dashboard and a global banner to inform customers.","ko":"Amazon Kinesis 는 스트리밍 데이터를 실시간으로 처리하는 서비스이고, 고객이 직접 쓸 뿐 아니라 여러 AWS 서비스가 쓴다. 스트림은 많은 백엔드 셀 클러스터가 처리하고, 프런트엔드 서버군이 샤딩으로 스트림을 백엔드에 나눈다. 프런트엔드는 인증, 스로틀링, 알맞은 스트림 샤드로 요청을 보내는 일을 맡는다. 프런트엔드 서버마다 백엔드 클러스터의 구성원 정보와 샤드 소유 정보를 담은 shard-map 이라는 캐시를 둔다. 서버는 이 정보를 구성원 정보를 내주는 마이크로서비스, DynamoDB 의 설정 정보, 다른 프런트엔드 서버가 보내는 메시지에서 얻는다. 다른 서버의 메시지를 받으려고 프런트엔드 서버는 서버군의 다른 서버마다 운영체제 스레드를 하나씩 만든다. 그래서 서버마다 유지할 스레드 수는 서버군의 서버 수에 비례한다.\n\n2020년 11월 25일 2:44 AM PST 부터 3:47 AM PST 까지 US-EAST-1 의 프런트엔드 서버군에 비교적 작은 용량을 더했다. 기존 서버가 새 서버를 알아채는 데 최대 한 시간이 걸린다. 5:15 AM PST 에 Kinesis 레코드를 넣고 가져오는 호출의 오류 알람이 울리기 시작했다. 오류가 여러 가지여서 진단이 늦어졌고, 팀은 조심하려고 새 용량을 빼기 시작했다. 7:51 AM PST 에 원인 후보를 두어 개로 좁혔고, 어느 후보든 프런트엔드 서버군 전체를 재시작해야 한다고 판단했다. 프런트엔드 서버에서는 shard-map 을 채우는 자원과 들어오는 요청을 처리하는 자원이 서로 다툰다. 그래서 서버를 너무 빨리 올리면 요청을 처리할 자원이 모자라 오류와 지연이 늘고, 느린 서버가 비정상으로 판정돼 서버군에서 빠질 수 있었다. 팀은 조사와 함께, 서버가 시작할 때 이웃 프런트엔드 서버 대신 정본 메타데이터 저장소에서 바로 데이터를 받도록 설정을 넣기 시작했다.\n\n9:39 AM PST 에 근본 원인을 확인했다. 새 용량 때문에 서버군의 모든 서버가 운영체제 설정이 허용하는 최대 스레드 수를 넘었다. 그래서 캐시를 다 만들지 못했고, 프런트엔드 서버는 쓸모없는 shard-map 을 들고 백엔드 클러스터로 요청을 보내지 못했다. 팀은 더 시험하지 않은 채 운영체제 한도를 올리지는 않기로 했다. 촉발 요인이 된 추가 용량을 막 다 뺀 참이어서 스레드 수가 더는 한도를 넘지 않는다고 보고 재시작을 진행했다. 10:07 AM PST 에 첫 서버 묶음이 Kinesis 트래픽을 받기 시작했다. 프런트엔드 서버군은 서버 수천 대로 이루어져 있는데, 서버는 시간당 수백 대씩만 다시 더할 수 있었다. 정오부터 오류율이 꾸준히 내려갔고, Kinesis 는 10:23 PM PST 에 완전히 정상으로 돌아왔다.\n\nKinesis 를 쓰는 다른 서비스도 실패했다. 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 를 써서 대시보드를 갱신하지 못했다. 의존이 적은 예비 도구는 동작했지만 지원 담당자에게 익숙하지 않아 게시가 늦었다."},"trigger":{"en":"A relatively small addition of capacity to the Kinesis front-end fleet, made between 2:44 AM and 3:47 AM PST.","ko":"2:44 AM PST 부터 3:47 AM PST 까지 Kinesis 프런트엔드 서버군에 비교적 작은 용량을 더했다. AWS 는 이것이 촉발 요인이었지만 근본 원인은 아니었다고 밝혔다."},"severity":"unknown","symptoms":["high-error-rate","high-latency","monitoring-down"],"timeline":{"detected_after":null,"resolved_after":"17h 8m"},"date_kind":"incident","detection":{"en":"Alarms for errors on putting and getting Kinesis records fired at 5:15 AM PST, and the teams began reviewing logs.","ko":"5:15 AM PST 에 Kinesis 레코드를 넣고 가져오는 호출의 오류 알람이 울리기 시작했고, 팀이 로그를 보기 시작했다."},"components":["message-broker","serverless-functions","telemetry-agent"],"root_cause":"capacity","remediation":[{"text":{"en":"Removed the newly added front-end capacity","ko":"조심하려고 다른 오류를 조사하면서 새로 더한 프런트엔드 용량을 빼기 시작했다."}},{"text":{"en":"Added a configuration so front-end servers load bootstrap data from the authoritative metadata store instead of neighbouring servers","ko":"재시작을 빠르게 하려고, 프런트엔드 서버가 시작할 때 이웃 프런트엔드 서버 대신 정본 메타데이터 저장소에서 바로 데이터를 받도록 설정을 넣기 시작했다."}},{"text":{"en":"Restarted the front-end fleet gradually, a few hundred servers per hour from 10:07 AM PST","ko":"10:07 AM PST 부터 프런트엔드 서버를 다시 올리며 시간당 수백 대씩 천천히 트래픽을 더했다."}},{"text":{"en":"Added Cognito capacity to buffer more calls to Kinesis","ko":"Cognito 팀은 장애 초기에 용량을 더해 Kinesis 호출을 버퍼링할 여유를 늘렸다."}},{"text":{"en":"Deployed a change that reduced Cognito's dependency on Kinesis","ko":"10:15 AM PST 에 Cognito 의 Kinesis 의존을 줄이는 변경을 배포하기 시작했고, 오류율이 내려가기 시작했다."}},{"text":{"en":"Mitigated the memory contention on the Lambda invocation hosts","ko":"10:36 AM PST 에 엔지니어들이 Lambda 함수 호출 호스트의 메모리 경합을 줄이는 조치를 해서 호출 오류가 풀렸다."}},{"text":{"en":"Informed customers through the backup Service Health Dashboard tool, the Personal Health Dashboard and a global banner","ko":"의존이 적은 예비 도구로 Service Health Dashboard 에 게시하고, Personal Health Dashboard 로 영향받은 고객에게 직접 알리고, Service Health Dashboard 에 전역 배너 요약을 올려 고객에게 상황을 알렸다."}}],"action_items":[{"text":{"en":"Move the Kinesis front-end to larger CPU and memory servers so fewer servers, and fewer threads per server, are needed","ko":"CPU 와 메모리가 더 큰 서버로 옮겨 서버 수를 줄이고, 서버마다 서버군 안에서 통신하는 데 필요한 스레드 수를 줄인다."}},{"text":{"en":"Add fine-grained alarming for thread consumption","ko":"서비스의 스레드 사용량에 세밀한 알람을 더한다."}},{"text":{"en":"Finish testing a higher operating system thread count limit","ko":"운영체제 설정의 스레드 수 한도를 올리는 시험을 마친다."}},{"text":{"en":"Greatly improve the cold-start time of the front-end fleet","ko":"프런트엔드 서버군의 콜드 스타트 시간을 크게 줄이는 변경을 한다."}},{"text":{"en":"Move the front-end server cache to a dedicated fleet","ko":"프런트엔드 서버 캐시를 전용 서버군으로 옮긴다."}},{"text":{"en":"Move a few large AWS services such as CloudWatch to a separate, partitioned front-end fleet","ko":"CloudWatch 같은 큰 AWS 서비스 몇 개를 따로 나눈 프런트엔드 서버군으로 옮긴다."}},{"text":{"en":"Accelerate the cellularization of the front-end fleet to match the back-end","ko":"백엔드에서 한 것처럼 프런트엔드 서버군의 셀 단위 분리를 크게 앞당긴다."}},{"text":{"en":"Change the Cognito webservers so they sustain Kinesis API errors without exhausting their buffers","ko":"Cognito 웹 서버가 Kinesis API 오류를 겪어도 버퍼를 다 쓰지 않고 버티도록 고쳤다."}},{"text":{"en":"Keep 3 hours of metric data in the CloudWatch local metrics data store, first in US-EAST-1 and then globally","ko":"CloudWatch 로컬 지표 데이터 저장소에 지표 데이터 3시간 치를 보관해, CloudWatch 사용자와 AutoScaling 같은 서비스가 최근 지표를 바로 읽게 한다. US-EAST-1 에는 적용을 마쳤고 앞으로 몇 주 동안 전 세계에 배포한다."}},{"text":{"en":"Train support engineers regularly on the backup tool for posting to the Service Health Dashboard","ko":"지원 엔지니어가 Service Health Dashboard 예비 게시 도구를 정기적으로 훈련받도록 지원 교육을 바꿨다."}}],"contributing":["limit-unknown","blast-radius-too-wide","circular-dependency"],"recurrence_of":null,"symptoms_text":{"en":"At 5:15 AM PST on 25 November 2020, alarms fired for errors on putting and getting Amazon Kinesis records in the Northern Virginia (US-EAST-1) Region. From the same time CloudWatch, which processes metric and log data through Kinesis Data Streams, and CloudWatch Events and EventBridge returned more errors.\n\nErrors appeared in every kind of call made by both existing and new front-end servers, and many of them had nothing to do with the front-end capacity added that morning and would probably have stayed if it were removed. The variety of errors made side effects hard to tell apart from the cause and slowed diagnosis. The new capacity was removed anyway as a precaution. By 7:51 AM PST the team had narrowed the cause to a couple of candidates, the leading one an issue that seemed to create memory pressure, but the cause confirmed at 9:39 AM PST was not memory pressure.\n\nCloudWatch had more errors and latency on the PutMetricData and PutLogEvents APIs, alarms went into the INSUFFICIENT_DATA state, and most metrics were not processed, which left gaps in CloudWatch metrics. Cognito User Pools and Identity Pools had more API failures and latency, so external users could not authenticate or get temporary AWS credentials. Lambda function invocations had more errors from 6:15 AM PST, reactive AutoScaling policies were delayed, and CloudWatch Events and EventBridge had API errors and delayed event processing, which affected cluster provisioning, scaling and task de-provisioning in ECS and EKS.\n\nAWS could not update the Service Health Dashboard at first, because the tool used to post updates itself uses Cognito. The backup tool worked but is more manual and less familiar to support operators, so early updates were delayed.","ko":"2020년 11월 25일 5:15 AM PST 에 Kinesis 레코드를 넣고 가져오는 호출의 오류 알람이 울리기 시작했다. Kinesis 를 쓰는 CloudWatch, CloudWatch Events, EventBridge 도 같은 시각부터 오류와 지연을 보였다.\n\n오류는 한 종류가 아니었다. 기존 프런트엔드 서버와 새로 더한 서버가 하는 여러 호출에서 단계를 가리지 않고 오류가 났다. 그래서 부작용과 근본 원인을 가려내기 어려웠다.\n\n팀은 새로 더한 용량을 의심했다. 그러나 새 용량과 상관없어 보이고 용량을 빼도 남을 것 같은 오류가 많았다. 그래도 조심하려고 다른 오류를 조사하면서 새 용량을 빼기 시작했다.\n\n7:51 AM PST 에 근본 원인 후보를 두어 개로 좁혔다. 가장 유력한 후보는 메모리 압박을 일으키는 듯한 문제였지만, 9:39 AM PST 에 확인한 원인은 메모리 압박이 아니었다.\n\nCloudWatch 에서는 PutMetricData 와 PutLogEvents API 의 오류율과 지연이 올라갔고, 알람이 INSUFFICIENT_DATA 상태로 바뀌었다. Cognito User Pools 와 Identity Pools 에서는 API 실패와 지연이 늘어 외부 사용자가 인증하거나 임시 AWS 자격 증명을 받지 못했다.\n\n장애 초기에는 Service Health Dashboard 를 갱신할 수 없었다. 갱신에 쓰는 도구가 Cognito 를 쓰고 있었기 때문이다."},"updated_at":"2026-11-14T12:34:03.547450Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0384","org_slug":"amazon-web-services"}