글

Lambda 프록시 통합 vs 표준 통합: API Gateway 이벤트 객체 구조 완전 분석

API Gateway를 처음 설정할 때 'Lambda 프록시 통합' 체크박스 하나가 이벤트 객체 구조 전체를 바꾼다는 사실을 모르고 넘어가면, Lambda 핸들러에서 event.body 가 undefined 로 찍히는 상황을 마주하게 된다. 이 글은 두 통합 방식의 내부 동작 차이와 그로 인한 이벤트 포맷 변화를 실제 운영 관점에서 정리한다. TL;DR — Lambda 프록시 통합 핵심 요약 항목 Lambda 프록시 통합 Lambda 표준 통합 이벤트 구조 API Gateway가 고정 포맷으로 전달 매핑 템플릿으로 개발자가 직접 정의 요청 매핑 템플릿 불필요 (자동 처리) 필수 작성 응답 매핑 템플릿 불필요 (Lambda 반환값 그대로) 필수 작성 HTTP 상태코드 제어 Lambda 반환 객체 내 statusCode 필드 API Gateway 매핑 규칙 헤더 접근 event.headers 로 직접 접근 매핑 템플릿에서 명시적으로 추출 필요 설정 복잡도 낮음 높음 (VTL 템플릿 작성) 유연성 포맷 고정 완전한 변환 제어 가능 Lambda 프록시 통합이란 무엇인가 API Gateway에서 Lambda를 백엔드로 사용할 때 두 가지 통합 방식을 선택할 수 있다. Lambda 프록시 통합(Lambda Proxy Integration) 은 API Gateway가 HTTP 요청 전체 — 메서드, 경로, 쿼리스트링, 헤더, 바디 — 를 하나의 표준화된 JSON 이벤트 객체로 패키징해서 Lambda에 그대로 전달하는 방식이다. 반대로 Lambda 표준 통합(Lambda Non-Proxy Integration) 은 개발자가 Velocity Template Language(VTL)로 작성한 매핑 템플릿을 통해 요청과 응답을 변환하는 방식이다. 프록시 통합에서 'Pro...

여러 EC2 인스턴스 간 폴더 공유: EBS vs EFS 완전 비교 가이드

5개의 EC2 인스턴스가 동일한 디렉토리를 읽고 써야 하는 상황이 생겼다. 처음엔 EBS 볼륨 하나를 여러 인스턴스에 붙이면 되지 않을까 생각했는데, 실제로 해보려고 하면 콘솔에서 막히거나 데이터가 꼬이는 경험을 하게 된다. 이 글은 여러 EC2 인스턴스 간 스토리지 공유 문제를 EBS와 EFS 관점에서 실제 운영 경험 기반으로 정리한다. TL;DR — EBS vs EFS 핵심 비교 항목 EBS (일반 볼륨) EBS Multi-Attach EFS 동시 다중 인스턴스 마운트 ❌ 불가 ⚠️ 제한적 가능 ✅ 기본 지원 파일시스템 공유 ❌ ❌ (클러스터 파일시스템 필요) ✅ NFS v4.1/4.2 AZ 제약 동일 AZ만 동일 AZ만 리전 전체 (멀티 AZ) 일반적 공유 폴더 용도 ❌ ❌ ✅ 운영 복잡도 낮음 높음 낮음 결론부터: 5개 EC2 인스턴스가 동일 폴더를 공유하려면 EFS를 사용 해야 한다. EBS는 구조적으로 단일 인스턴스 전용 블록 스토리지이며, Multi-Attach는 공유 파일시스템을 제공하지 않는다. EBS와 EFS의 동작 원리 — 왜 EBS는 공유가 안 되는가 EBS는 블록 스토리지다. 인스턴스에 마운트되면 해당 OS가 파일시스템(ext4, xfs 등)을 직접 관리한다. 두 인스턴스가 동시에 같은 EBS 볼륨을 마운트하면, 각 OS가 독립적으로 파일시스템 메타데이터를 쓰게 되어 데이터 손상이 발생한다. 이건 AWS 제약이 아니...

AWS T3 인스턴스 CPU 크레딧 완전 이해: 갑작스러운 성능 저하의 진짜 원인

배포 직후엔 멀쩡하던 서버가 트래픽이 몰리고 나서 갑자기 응답이 느려진다. CPU 사용률을 보면 100%도 아닌데 레이턴시는 치솟는다. T3 인스턴스를 운영하다 보면 한 번쯤 마주치는 상황이고, 원인을 모르면 인스턴스 타입을 무작정 업그레이드하게 된다. 문제는 CPU 크레딧이다. TL;DR — T3 CPU 크레딧 핵심 요약 항목 내용 T3 동작 방식 기준선(Baseline) 이하 사용 시 크레딧 적립, 초과 시 소진 크레딧 소진 시 동작 Standard 모드: CPU가 기준선으로 스로틀링 / Unlimited 모드: 추가 과금 후 버스트 유지 T3 기본 모드 Unlimited (T3 출시 이후 기본값) 성능 저하 주요 원인 Standard 모드에서 크레딧 고갈, 또는 Unlimited 모드에서 예상치 못한 추가 비용 진단 지표 CloudWatch: CPUCreditBalance, CPUSurplusCreditsCharged T3 버스터블 인스턴스의 동작 원리 T3는 일반 인스턴스와 달리 vCPU를 항상 전속력으로 쓸 수 없다. 인스턴스 크기마다 정해진 CPU 기준선(Baseline) 이 있고, 그 이하로 사용하면 크레딧이 쌓이고, 초과하면 크레딧을 소진하는 구조다. 크레딧이 있을 때만 기준선 이상의 CPU 성능을 낼 수 있다. 기준선은 인스턴스 크기에 따라 다르다. 예를 들어 t3.micro는 vCPU 2개 기준으로 약 10%의 기준선을 가진다. 즉, 평균 CPU 사용률이 10% 이하일 때 크레딧이 적립되고, 10%를 넘으면 크레딧을 소진한다. 정확한 기준선 수치는 인스턴스 크기마다 다르므로 AWS 공식 문서 에서 확인해야 한다. 크레딧 시스템은 은행 계좌와 비슷하다. 조용할 때 저축하고, 바쁠 때 인출한다. 잔고가 바닥나면 더 이상 인출할 수 없다 — Standard 모드에서는. g...

S3 파일 삭제 복구: 버전 관리로 이전 버전 찾고 되살리기

S3에서 파일을 실수로 삭제했을 때, 버킷에 버전 관리(Versioning)가 활성화되어 있었다면 데이터는 실제로 사라진 게 아니다. AWS S3 버전 관리는 삭제 작업을 '삭제 마커(Delete Marker)' 삽입으로 처리하기 때문에, 이전 버전 객체는 여전히 스토리지에 남아 있다. 이 글은 그 버전을 찾아서 복원하는 정확한 절차를 다룬다. TL;DR — S3 삭제 복구 핵심 요약 단계 작업 핵심 포인트 1 버전 목록 조회 list-object-versions 로 삭제 마커와 이전 버전 확인 2 삭제 마커 제거 삭제 마커의 VersionId 를 지정해 delete-object 실행 3 복원 검증 head-object 로 객체 접근 가능 여부 확인 대안 특정 버전 복사 원하는 VersionId 를 copy-object 로 현재 버전으로 승격 S3 버전 관리가 삭제를 처리하는 방식 버전 관리가 활성화된 버킷에서 aws s3 rm 또는 DeleteObject API를 VersionId 없이 호출하면, S3는 해당 객체를 물리적으로 제거하지 않는다. 대신 동일한 키(Key)에 '삭제 마커'라는 특수 버전을 추가한다. 이후 일반적인 GetObject 요청은 405 Method Not Allowed 가 아닌 404 NoSuchKey 를 반환하는데, 이게 실제 삭제처럼 보이는 이유다. 삭제 마커 자체도 고유한 VersionId 를 가진다. 이 마커를 제거하면 이전 버전이 다시 '현재 버전'으로 노출된다. 즉, 복원의 핵심은 데이터를 되살리는 게 아니라 삭제 마커를 지우는 것이다. sequenceDiagram participant User as 사용자 participant S3 as S3 버킷 Note over S3: 버전 관리 활성화...

Lambda에서 Private RDS 연결 안 될 때 — VPC 설정부터 Security Group까지 완전 진단

Lambda 함수가 Private Subnet에 있는 RDS 인스턴스에 연결되지 않는 상황은 생각보다 자주 발생한다. 'Lambda에서 Private RDS 연결'을 처음 구성할 때 가장 많이 놓치는 부분이 Lambda 자체에 VPC 설정을 붙여야 한다는 사실이다 — Lambda는 기본적으로 AWS 관리 네트워크에서 실행되기 때문에, VPC 내부 리소스에는 아예 도달할 수 없다. TL;DR — Lambda에서 Private RDS 연결 핵심 요약 항목 설명 Lambda VPC 설정 필요 여부 필수. Subnet ID와 Security Group ID를 Lambda에 지정해야 함 Lambda용 Subnet 선택 RDS와 동일한 VPC 내 Private Subnet (가용 영역 2개 이상 권장) Security Group 규칙 Lambda SG → RDS SG 인바운드 허용 (포트 3306/5432) 인터넷 액세스 필요 시 NAT Gateway 경유 라우팅 필요 (IGW 직접 연결 불가) IAM 권한 Lambda 실행 역할에 VPC ENI 생성 권한 필요 연결 진단 순서 VPC 설정 → SG 규칙 → Subnet 라우팅 → IAM → RDS 상태 Lambda가 Private RDS에 연결되는 원리 Lambda 함수는 기본 실행 환경에서 AWS 관리 네트워크에 위치한다. 이 상태에서는 퍼블릭 엔드포인트(S3, DynamoDB 등)에는 접근할 수 있지만, 고객 VPC 내부의 RDS처럼 프라이빗 리소스에는 네트워크 경로 자체가 없다. Lambda에 VPC 설정을 추가하면, AWS는 Lambda 실행 환경과 고객 VPC 사이에 Hyperplane ENI(Elastic Network Interface) 를 생성한다. 이 ENI가 지정한 Subnet에 배치되고, 지정한 Security...

ElastiCache Redis 도입 시점: RDS 반복 읽기 쿼리 성능 개선 실전 가이드

RDS 인스턴스의 CPU와 커넥션 수가 치솟는데 슬로우 쿼리 로그를 열어보면 항상 같은 쿼리들이 반복해서 찍혀 있다. 상품 목록, 사용자 세션, 설정값처럼 데이터는 거의 바뀌지 않는데 매 요청마다 DB를 치고 있는 상황 — ElastiCache Redis를 캐시 레이어로 추가하는 것이 ElastiCache Redis 도입 의 가장 전형적인 시나리오다. TL;DR — ElastiCache Redis 도입 판단 기준 판단 항목 Redis 도입 적합 도입 불필요 동일 쿼리 반복 비율 전체 읽기의 30% 이상이 동일 키 대부분 유니크 쿼리 데이터 변경 주기 수 분 ~ 수 시간 단위 실시간 갱신 필수 RDS 병목 지점 읽기 쿼리 과부하 쓰기 병목, 스키마 문제 응답 지연 허용 범위 수십 ms 이내 목표 DB 직접 조회로 충분 캐시 일관성 요구 Eventually Consistent 허용 Strong Consistency 필수 ElastiCache Redis가 RDS 부하를 줄이는 원리 Redis는 인메모리 데이터 구조 저장소다. RDS가 디스크 I/O와 쿼리 파싱, 실행 계획 수립을 거쳐 결과를 반환하는 동안, Redis는 메모리에서 키-값을 직접 조회해 반환한다. 이 구조적 차이가 응답 속도 격차를 만든다. 캐시 히트 시 요청은 RDS에 도달하지 않는다. RDS 입장에서는 해당 쿼리가 존재하지 않는 것과 같다. 커넥션 풀 소모도 없고, 실행 계획 수립 비용도 없다. 트래픽이 몰리는 구간에서 RDS 커넥션 수가 안정적으로 유지되는 이유가 여기에 있다. graph LR App["애플리케이션 서버"] Redis["ElastiCache Redis"] RDS["Amazon RDS"] App -->|"① GE...

DynamoDB LSI vs GSI: 다른 속성으로 쿼리할 때 무엇을 선택해야 하는가

DynamoDB 테이블을 설계하다 보면 반드시 마주치는 상황이 있다. 기본 키로는 조회가 잘 되는데, 다른 속성으로도 쿼리해야 하는 요구사항이 생기는 것이다. 이때 LSI(Local Secondary Index)와 GSI(Global Secondary Index) 중 무엇을 써야 하는지 판단하지 못하면, 나중에 테이블을 통째로 재설계해야 하는 상황이 온다. TL;DR: LSI vs GSI 핵심 비교 항목 LSI GSI 파티션 키 기본 테이블과 동일 다른 속성 지정 가능 정렬 키 다른 속성으로 변경 가능 선택적으로 지정 생성 시점 테이블 생성 시에만 가능 언제든지 추가/삭제 가능 일관성 읽기 강력한 일관성 지원 최종적 일관성만 지원 처리량 공유 기본 테이블과 공유 독립적으로 프로비저닝 파티션당 크기 제한 10GB (파티션 키 값 기준) 제한 없음 테이블당 최대 개수 5개 20개 (기본값, 조정 가능) DynamoDB 인덱스가 동작하는 방식 LSI와 GSI를 선택하기 전에, 두 인덱스가 내부적으로 어떻게 다른지 이해해야 한다. 잘못된 선택은 단순히 성능 문제로 끝나지 않는다. LSI는 테이블 생성 후 추가할 수 없기 때문에, 나중에 필요하다는 걸 알았을 때는 이미 늦다. LSI: 같은 파티션 안에서의 다른 정렬 방식 LSI는 기본 테이블과 동일한 파티션 키를 사용한다. 달라지는 것은 정렬 키뿐이다. 물리적으로 ...