DEV 트랙 스포트라이트: 서버리스 아키텍처에서 실패를 포용하는 예술 (DEV312)
Source: Dev.to
Serverless 아키텍처는 분산 시스템의 막대한 힘에 포장된 단순함을 약속합니다. 하지만 AWS Data Hero이자 F‑Secure의 수석 클라우드 아키텍트인 Anahit Pogosova가 DEV312 세션에서 우리에게 상기시킨 바와 같이, 단순함은 환상에 불과합니다.
“Serverless managed services are a step up in the abstraction ladder.
They make the underlying infrastructure seem almost invisible, almost magical.
But by using serverless services, we didn’t just magically teleport to a different reality.
We are still living in the very same messy physical world with all its underlying complexities.”“서버리스 관리형 서비스는 추상화 단계에서 한 단계 올라갑니다.
이들은 기본 인프라를 거의 보이지 않게, 거의 마법처럼 보이게 합니다.
하지만 서버리스 서비스를 사용한다고 해서 우리는 마법처럼 다른 현실로 순간이동한 것이 아닙니다.
우리는 여전히 그 모든 기본 복잡성을 가진 동일하고 지저분한 물리적 세계에 살고 있습니다.”
그녀의 세션은 실제 전쟁 이야기를 무기로 삼아 분산 시스템의 숨겨진 함정을 탐험하고 회복력을 구축하기 위한 실용적인 전략을 제시했습니다.
전체 세션 보기:
(embed or link to the video here)
The False Sense of Security
서버리스 추상화 레이어는 위험한 착각을 만들어냅니다. 서비스를 선택하고, 서로 연결하고, “그냥 작동한다”는 것을 보면서 우리는 그 아래에 숨어 있는 분산 시스템의 복잡성을 잊어버릴 수 있습니다. Anahit이 말했듯이:
“서버리스 아키텍처는 여러분이 확실히 존재한다는 것을 몰랐던 컴퓨터의 장애가 전체 아키텍처를 사용할 수 없게 만들 수 있는 경우를 말합니다.”
이러한 높은 수준의 추상화는 실패가 우리에게서 추상화되기 때문에 잠재적인 문제를 발견하기 어렵게 만듭니다. 하지만 그 실패가 사라진 것은 아니며, 여전히 기본 분산 시스템에 내장되어 나타나기를 기다리고 있습니다.
실제 사례
Anahit은 대규모 실시간 데이터 스트리밍 아키텍처를 구축한 경험을 공유했습니다. 구성은 매우 단순해 보였습니다:
- Producer → Amazon Kinesis Data Streams
- Consumer → AWS Lambda (레코드 처리)
완벽하게 작동했습니다—하지만 데이터가 손실되고 있다는 사실을 전혀 알지 못했습니다.
서로 연결된 세 가지 문제
-
설정되지 않은 타임아웃 – JavaScript SDK의 기본 타임아웃은 무한이었습니다(이전 SDK v2에서는 2분). 네트워크 오류로 Kinesis 요청이 타임아웃되면, 프로듀서는 자원을 모두 소모해 새로운 데이터를 처리할 수 없게 됩니다.
-
처리되지 않은 부분 실패 –
Kinesis.PutRecords와 같은 배치 작업은 원자적이지 않습니다. 배치의 일부는 성공하고 나머지는 실패할 수 있습니다(예: 트래픽 급증 시 샤드 제한에 걸리는 경우). SDK는 성공을 반환하지만, 부분 실패를 감지하고 처리하는 것은 여러분의 책임입니다. -
기본 재시도 동작 – Lambda가 잘못된 레코드를 처리하지 못하면 전체 배치를 무한히 재시도합니다(레코드가 24 시간 후에 만료될 때까지). 하나의 “독성 레코드”(poison‑pill)가 전체 샤드를 차단해, 레코드가 만료되는 속도가 Lambda가 따라잡는 속도보다 빨라지면서 연쇄적인 데이터 손실이 발생합니다.
Anahit은 타임아웃과 재시도를 “숨겨진 초능력”이라고 부릅니다. 복원력에 매우 강력하지만, 잘못 사용하면 크게 역효과를 낼 수 있기 때문입니다.
타임아웃 및 재시도 모범 사례
- 기본 타임아웃 값을 무조건 신뢰하지 마세요. AWS SDK 요청에 대해 서비스와 지연 시간 기대치에 맞는 적절한 타임아웃을 설정하십시오. 너무 길면 자원을 낭비하고, 너무 짧으면 조기에 재시도가 발생해 하위 시스템을 압도합니다.
“코드를 다시 살펴볼 때, 네트워크를 통해 전송되는 모든 요청을 확인하세요. 그 타임아웃 값이 무엇인지 확실히 알아두세요. 그리고 그것들을 직접 제어하고 있는지 확인하세요.” – Anahit
- 재시도는 본질적으로 이기적입니다. 잘못 구현된 재시도는 작은 문제를 연쇄적인 장애로 확대시켜 전체 시스템을 다운시킬 수 있습니다.
“재시도는 다른 모든 원인보다 더 많은 분산 시스템을 다운시켰습니다.” – Gregor Hohpe
안전한 재시도를 위한 핵심 원칙
- 일시적인 실패에만 재시도 – 도움이 되지 않는 경우(예: 과부하된 시스템이나 부작용이 있는 작업)에는 재시도하지 마세요.
- 상한선 설정 – 도움이 되지 않을 때는 재시도를 중단해 연쇄 장애를 방지합니다.
- 지터가 포함된 지수 백오프 사용 – 재시도 시도를 고르게 분산시켜 시스템 과부하를 방지합니다. 지터는 지수 백오프에 무작위성을 추가해 재시도 성공률을 크게 높입니다.
Lambda 이벤트 소스 매핑 – 숨겨진 구성 요소
대부분의 개발자는 Lambda의 event source mapping에 대해 들어본 적이 없지만, Kinesis, DynamoDB Streams 등과 함께 Lambda를 사용할 때는 매우 중요합니다. 이 숨겨진 구성 요소는 레코드를 읽고, 배치화하며, 여러분의 Lambda 함수를 호출합니다.
기본적으로, Lambda가 배치를 처리하지 못하면 레코드가 만료될 때까지(예: Kinesis는 24 시간 이상) 무한히 재시도합니다. 하나의 나쁜 레코드가 “독성 알약”이 되어 전체 샤드를 차단하면 다음과 같은 문제가 발생합니다:
- 여전히 비용이 청구되는 쓸모없는 호출
- 동일한 데이터를 반복적으로 재처리
- 재시도가 계속되는 동안 샤드 전체가 차단
- 레코드가 만료되면서 발생하는 연쇄적인 데이터 손실
Source: …
pire faster than Lambda can catch up
이벤트 소스 매핑 구성
| Parameter | Purpose (목적) | Default |
|---|---|---|
MaximumRetryAttempts | 재시도 횟수 제한 | -1 (무한) |
MaximumRecordAge | 레코드가 스트림에 머무를 수 있는 시간 제한 설정 | -1 (제한 없음) |
BisectBatchOnFunctionError | 실패한 배치를 분할하여 문제 레코드 격리 | false |
DestinationConfig | 실패한 레코드를 분석을 위해 SQS 또는 SNS로 라우팅 | none |
ParallelizationFactor | 처리량 확장 (Lambda 동시 실행 제한을 고려) | 1 |
“무엇을 하든, 기본값을 사용하지 말아 주세요.” – Anahit
용량 제한 – “무한” 확장성의 현실
Serverless는 확장성을 약속하지만, 이를 무한 확장성으로 오해하기 쉽습니다. 현실은 모든 사용자가 자원을 공유하고, 서비스 제한이 단일 사용자가 용량을 독점하지 못하도록 한다는 점입니다.
- Kinesis 샤드 – 샤드당 초당 1 MiB 또는 1,000 레코드.
- Lambda 동시성 – 계정/리전당 기본 1,000 동시 실행.
이 제한에 도달하면 요청이 제한(throttled)되어 실패합니다. 예를 들어, 100개의 샤드를 가진 Kinesis 스트림에 병렬화 팩터 10을 사용하면 전체 Lambda 동시성 할당량을 소진하게 되어, 동일 계정 내 다른 Lambda 함수들이 실패할 수 있습니다.
실패를 현실로 받아들이기
분산 시스템에서는 모든 것이 언제든지 실패합니다. 이러한 사고방식으로 설계하면—적절한 타임아웃, 제한된 재시도, 신중한 구성—Serverless가 취약한 환상이 아니라 탄력적인 프로덕션 준비 아키텍처가 됩니다.
시간 관련 모범 사례
-
타임아웃 계획 – 기본값을 신뢰하지 마세요. 사용 사례에 맞는 명시적인 타임아웃 값을 설정하세요.
-
안전한 재시도 구현 – 일시적인 실패만 재시도하고, 제한을 적용하며, 지터가 포함된 지수 백오프를 사용하세요.
-
부분 실패 처리 – 배치 작업은 원자성이 없으므로, 실패한 부분을 감지하고 재시도하세요.
-
서비스 한계 파악 – 용량 제한 및 스로틀링 동작을 이해하세요.
-
이벤트 소스 매핑 구성 – Kinesis/DynamoDB 스트림과 함께 사용하는 Lambda의 기본 설정에 의존하지 마세요.
-
편집증을 가지세요 (좋은 의미로) – Martin Kleppmann이 말했듯이:
“분산 시스템에서는 의심, 비관, 그리고 편집증이 보상을 가져다준다.”
-
Anahit의 마무리 조언 –
“분산 시스템과 아키텍처는 어렵지만, 실제 세계의 혼돈을 받아들이는 귀중한 기술을 가르쳐 줍니다. 각 실패는 더 나은 방식을 찾고, 시스템을 더욱 탄력적으로 만들 기회입니다.”
-
Dr. Werner Vogels의 상기 –
“모든 것은 언제나 실패합니다.” 우리가 할 수 있는 가장 좋은 일은 차분함을 유지하고, 그런 실패가 발생했을 때 대비하는 것입니다.
이 게시물에 대하여
이 게시물은 DEV Track Spotlight 시리즈의 일부로, AWS re:Invent 2025 Developer Community (DEV) 트랙에서 진행된 놀라운 세션들을 조명합니다.
DEV 트랙 개요
- 60개의 고유 세션
- 93명의 발표자는 AWS 커뮤니티(AWS 히어로, 커뮤니티 빌더, 사용자 그룹 리더)와 AWS 및 Amazon 직원으로 구성
다루는 주제
| Category | Highlights |
|---|---|
| 🤖 GenAI & Agentic AI | 멀티 에이전트 시스템, Strands Agents SDK, Amazon Bedrock |
| 🛠️ Developer Tools | Kiro, Kiro CLI, Amazon Q Developer, AI 기반 개발 |
| 🔒 Security | AI 에이전트 보안, 컨테이너 보안, 자동 복구 |
| 🏗️ Infrastructure | 서버리스, 컨테이너, 엣지 컴퓨팅, 가시성 |
| ⚡ Modernization | 레거시 앱 전환, CI/CD, 기능 플래그 |
| 📊 Data | Amazon Aurora DSQL, 실시간 처리, 벡터 데이터베이스 |
이 시리즈의 각 게시물은 하나의 세션을 깊이 파고들어 다음을 공유합니다:
- 핵심 인사이트
- 실용적인 시사점
- 전체 녹화 링크
re:Invent에 직접 참석했든 원격으로 따라잡았든, 이 세션들은 우리 개발자 커뮤니티의 최고를 보여줍니다—실제 코드, 실제 데모, 그리고 실제 학습 내용.
계속 지켜보세요 이 놀라운 세션들을 조명하고 DEV 트랙을 만든 발표자들을 축하합니다!