이번 주는 분석 데이터 스토어(Redshift, Athena, DynamoDB, RDS/Aurora)와 워크로드별 스토어 선택을 다뤘다. 나흘의 내용을 같은 축에 놓으면 차이가 한눈에 보인다.
축 Redshift Redshift Spectrum Athena DynamoDB RDS / Aurora 본질 컬럼형 MPP 웨어하우스 웨어하우스에서 S3 외부 테이블 조회 서버리스 S3 쿼리 키-값 NoSQL 행 기반 관계형 OLTP 데이터 위치 클러스터(관리형 스토리지) S3 S3 테이블 파티션 인스턴스 볼륨 / 클러스터 볼륨 잘하는 일 반복되는 대량 집계·복잡한 조인 웨어하우스 + S3 이력 조인 간헐적 애드혹 SQL 키로 밀리초 조회, 대규모 동시성 트랜잭션, 조인, 제약 조건 못하는 일 건당 트랜잭션 쓰기(읽기 전용) 밀리초 응답, 행 단위 수정(Iceberg 제외) 임의 컬럼 집계, 조인 수억 행 컬럼 집계 과금 단위 노드 시간 또는 RPU-시간 + 스토리지 스캔량 스캔량(쿼리당 최소 10MB) 요청 단위 또는 프로비저닝 용량 인스턴스 시간 + 스토리지 조절 손잡이 분산 키, 정렬 키, WLM 파티션, 파일 포맷 파티션, 파일 포맷, 워크그룹 파티션 키, GSI, 용량 모드 인덱스, Read Replica 일관성 트랜잭션 파일 시점 파일 시점 결과적(기본)·강한 읽기 선택 트랜잭션(ACID) 서버리스 선택지 Redshift Serverless - 기본이 서버리스 온디맨드 모드 Aurora Serverless
💡 관련 이론 : 컬럼형(Redshift·Parquet)은 "많은 행의 몇 컬럼 집계"에, 행 기반(RDS·Aurora)은 "한 행의 모든 컬럼을 읽고 고치기"에 강하다. DynamoDB 는 그 어느 쪽도 아니고 "키를 알면 바로"에 강하다. 지문에서 동사를 본다. 합산·추이·리포트면 컬럼형, 주문·결제·수정이면 행 기반, 조회·세션·상태면 키-값이다.
분산 시스템은 데이터를 나눠 놓고 병렬로 일한다. 나누는 기준이 한쪽으로 쏠리면 병렬성이 깨진다. 이번 주와 지난 주차들에서 본 쏠림은 모두 같은 구조다.
서비스 나누는 기준 쏠리면 증상 처방 Redshift DISTKEY 의 값 → 슬라이스 스큐 한 노드만 바쁘고 쿼리 전체가 그 슬라이스를 기다림 고르게 분포한 DISTKEY, 또는 EVEN DynamoDB 파티션 키의 해시 → 파티션 핫 파티션 테이블 용량은 남는데 특정 키만 스로틀 고른 키, 쓰기 샤딩 Kinesis Data Streams 파티션 키의 해시 → 샤드 핫 샤드 특정 샤드만 스로틀 고른 키(샤드 증설로는 못 푼다) S3 + Athena 파티션 키 → 프리픽스 파티션 크기 불균형·작은 파일 일부 파티션만 느림, 파일 수 폭증 파티션 키 재설계, 컴팩션
공통 원칙: 값의 종류가 많고 트래픽·행 수가 고르게 퍼지는 키 를 고른다. status, country, date 처럼 값이 적거나 한 값에 몰리는 키는 어디서나 나쁘다.
차이점: Redshift 는 조인 상대와 같은 키를 써야 재분배가 없어지므로 "고른 분포"와 "조인 키 일치" 사이에서 타협한다. DynamoDB 는 조인이 없으므로 접근 패턴만 보면 된다.
분석 쿼리를 빠르고 싸게 만드는 방법은 결국 읽지 않는 것 이다.
수준 Redshift Athena / Spectrum (S3) DynamoDB 큰 덩어리를 건너뜀 정렬 키 + zone map(1MB 블록의 최소·최대) 파티션 프루닝(프리픽스) 파티션 키로 한 파티션만 덩어리 안에서 건너뜀 블록 단위 건너뛰기 Parquet/ORC 의 구간별 통계 정렬 키 조건으로 범위만 컬럼을 건너뜀 컬럼형 저장 컬럼형 포맷 + 필요한 컬럼만 SELECT 인덱스 프로젝션(필요한 속성만 복사) 무력화되는 경우 정렬 키에 함수 적용, 미정렬 영역 파티션 키 조건 없음, CSV·JSON Scan + FilterExpression
세 스토어 모두 "조건을 걸었는데도 전부 읽는" 함정이 있다. Redshift 는 정렬 키가 아닌 컬럼 필터, Athena 는 파티션 키가 아닌 컬럼 필터, DynamoDB 는 키가 아닌 속성 필터(Scan)다.
스토어 돈이 나가는 곳 줄이는 방법 헛수고 Athena 스캔한 바이트 파티션, Parquet, 압축, 필요한 컬럼만, 결과 재사용 쿼리 실행 시간 단축만 노리기 Redshift Spectrum 스캔한 바이트 Athena 와 동일 클러스터 증설 Redshift 프로비저닝 노드가 켜져 있는 시간 적정 크기, 일시 중지, 피크는 동시성 스케일링 개별 쿼리의 스캔량 줄이기(요금은 그대로, 성능만 개선) Redshift Serverless 쿼리가 쓴 RPU-시간 기본 용량 조정, 최대 RPU-시간 한도 - DynamoDB 온디맨드 읽기·쓰기 요청 단위 Scan 제거, 작은 아이템, 불필요한 GSI 제거 용량 미리 줄이기(개념이 없음) DynamoDB 프로비저닝 설정한 용량 Auto Scaling, 꾸준한 워크로드에 사용 한가한 시간에 그대로 두기 RDS / Aurora 인스턴스 시간, 스토리지, (Aurora Standard 는 I/O) 적정 인스턴스, 분석 부하를 다른 스토어로 복제본을 무한정 늘리기
지문이 "비용을 최소화"라면 먼저 얼마나 자주 쓰는가 를 본다. 가끔이면 스캔량·요청 과금(Athena, 온디맨드, Serverless), 상시면 용량 과금(프로비저닝 Redshift·DynamoDB)이 싸다.
"OLTP 데이터를 분석하고 싶다"는 요구에는 경로가 여럿이다. 신선도와 운영 부담으로 고른다.
경로 신선도 운영 부담 변환 맞는 경우 Read Replica·Aurora 리더 복제 지연만큼 매우 낮음 없음 가벼운 리포트를 라이터에서 떼어 내기 페더레이션 쿼리(Athena·Redshift) 실시간(직접 조회) 낮음 쿼리에서 가끔 하는 조인, 옮길 가치가 없는 양 제로 ETL → Redshift Aurora·RDS 는 거의 실시간, DynamoDB 는 최소 15분 매우 낮음 없음(Redshift 안에서 가공) 운영 DB 를 웨어하우스에서 지속 분석 DMS(전체 적재 + CDC) 거의 실시간 중간(복제 인스턴스·태스크) 매핑·간단한 규칙 이종 엔진, 온프레미스, S3·Kinesis 등 다양한 타깃 DynamoDB Streams → Lambda 초 단위 중간(함수 코드) 코드로 변경 이벤트에 반응, 소규모 복제 Kinesis Data Streams → Firehose → S3 버퍼만큼 낮음 Firehose 변환 DynamoDB 변경을 레이크에 지속 적재 S3 export(DynamoDB)·스냅샷 export(RDS) 내보낸 시점 낮음 이후 Glue·Athena 로 운영 부하 없는 정기 스냅샷 분석 Glue ETL(JDBC, 북마크) 배치 주기 중간(잡 관리) 임의의 코드 복잡한 정제·조인이 필요한 적재
"운영 DB 에 부하를 주면 안 된다" → export, 제로 ETL, 읽기 복제본 (직접 Scan·페더레이션은 부하 발생)
"파이프라인을 관리하고 싶지 않다" → 제로 ETL
"엔진이 다르다 / 온프레미스다" → DMS (+ 스키마 변환)
"복제 중에 복잡한 변환이 필요하다" → Glue ETL
"변경이 생기는 즉시 반응해야 한다" → 스트림 + Lambda
"데이터를 옮기지 않고 가끔만 본다" → 페더레이션 쿼리
💡 관련 이론 : "운영(OLTP)과 분석(OLAP)은 서로 다른 엔진에 둔다"가 데이터 엔지니어링의 대원칙이다. 둘을 잇는 수단이 달라져 왔을 뿐이다. 직접 짠 ETL 에서 DMS 의 CDC 로, 다시 관리형 제로 ETL 로 가면서 운영 부담이 줄었다. 다만 변환이 필요한 순간에는 여전히 Glue 나 웨어하우스 안의 SQL 이 필요하다. 제로 ETL 이 없애 준 것은 E 와 L 의 관리이지 T 의 필요가 아니다.
헷갈리는 쌍 구분 Athena vs Redshift Spectrum 둘 다 S3 를 스캔량 과금으로 읽는다. Athena 는 단독 서버리스, Spectrum 은 Redshift 가 있어야 하고 내부 테이블과 조인하는 것이 목적 Redshift 적재 vs Spectrum 자주·빠르게 읽으면 적재, 가끔 읽는 대용량 이력이면 S3 에 두고 Spectrum DISTKEY vs SORTKEY DISTKEY = 어느 슬라이스에 둘까(조인·병렬성). SORTKEY = 슬라이스 안에서 어떤 순서로 둘까(블록 건너뛰기) DISTSTYLE ALL vs KEY ALL = 작고 잘 안 바뀌는 차원을 전 노드에 복제. KEY = 큰 테이블끼리 조인 키로 모으기 COMPOUND vs INTERLEAVED COMPOUND = 앞 컬럼 필터 위주. INTERLEAVED = 여러 컬럼 조합 필터, 유지보수 비쌈 동시성 스케일링 vs 리사이즈 스케일링 = 짧은 폭증에 임시 클러스터. 리사이즈 = 상시 용량 부족에 클러스터 자체를 키움 WLM vs 워크그룹 WLM = Redshift 의 큐·메모리·우선순위. 워크그룹 = Athena 의 결과 위치·스캔 한도·격리 Redshift QMR vs Athena 쿼리당 한도 둘 다 폭주 쿼리 방어. QMR 은 시간·행 수 등 지표 기반, Athena 는 스캔 바이트 기반 GSI vs LSI GSI = 다른 파티션 키, 언제든 추가, 결과적 일관성. LSI = 같은 파티션 키, 생성 시에만, 강한 일관성 가능 DynamoDB Streams vs Kinesis Data Streams Streams = 24시간, 중복 없음, Lambda 중심. KDS = 최대 1년, 더 많은 컨슈머, Firehose·Flink 연결 Read Replica vs Multi-AZ 복제본 = 읽기 분산(비동기). Multi-AZ = 가용성(대기 인스턴스는 읽기 불가) 제로 ETL vs DMS 제로 ETL = 정해진 조합의 관리형 복제, 변환 없음. DMS = 폭넓은 조합, 이종 마이그레이션, 직접 운영 CTAS vs 뷰 vs 머티리얼라이즈드 뷰 CTAS(Athena) = 결과를 S3 에 새 테이블로 쓴다. 뷰 = 쿼리만 저장. 머티리얼라이즈드 뷰(Redshift) = 결과를 저장하고 갱신한다 Athena 파티션 프로젝션 vs Redshift 정렬 키 프로젝션 = 파티션 메타데이터 조회를 없앰. 정렬 키 = 데이터 블록 읽기를 줄임
서비스 항목 값 Redshift 블록 크기 1MB(블록마다 최소·최대 기록) Redshift INTERLEAVED 정렬 키 컬럼 최대 8개 Redshift 수동 WLM 사용자 큐 최대 8개, 슬롯 합계 최대 50, 기본 큐 동시 실행 5 Redshift 동시성 스케일링 무료 크레딧 하루 1시간씩 적립, 최대 30시간 누적 Redshift 동시성 스케일링 클러스터 수 기본값 1 Redshift COPY 자동 분할 128MB 이상의 분할 가능한 파일 Redshift 분할 불가 파일 권장 크기 압축 후 1MB~1GB, 파일 수는 슬라이스 수의 배수 Redshift Serverless 기본 용량 기본값 128 RPU, 최소 4 RPU. 과금은 초 단위, 최소 60초 Spectrum · Athena 쿼리당 최소 과금 10MB Athena CTAS·INSERT INTO 파티션 한 번에 100개 Athena CTAS Parquet 기본 압축 GZIP Athena 쿼리 결과 재사용 기본 60분, 최대 7일 Athena 한 번의 스캔에서 읽는 파티션 최대 100만 개 DynamoDB 아이템 최대 크기 400KB DynamoDB 읽기·쓰기 단위 읽기 4KB(강한 일관성 1회 = 결과적 2회), 쓰기 1KB DynamoDB 파티션당 처리량 초당 읽기 3,000단위, 쓰기 1,000단위 DynamoDB 인덱스 수 GSI 기본 20개, LSI 5개 DynamoDB Query·Scan 응답 호출당 최대 1MB DynamoDB Streams 보존 / 샤드당 동시 리더 24시간 / 2개 DynamoDB 증분 export 구간 최소 15분, 최대 24시간 DynamoDB 새 온디맨드 테이블 초당 쓰기 4,000, 읽기 12,000 까지 Aurora 스토리지 복제 3개 AZ, 6개 스토리지 노드 Aurora 리더 수 최대 15개 Aurora 클러스터 볼륨 상한 128TiB(최신 엔진 버전은 256TiB) 제로 ETL DynamoDB → Redshift 최소 지연 15분
한 회사의 스토어 배치를 따라가며 선택의 이유를 붙여 본다.
[모바일 앱]
├─ 장바구니·세션 ─────► DynamoDB(온디맨드) ──Kinesis Data Streams──► Firehose ──► S3 (행동 로그 레이크)
└─ 주문·결제 ─────────► Aurora(라이터 + 리더)
├─ 리더 ──────────► 고객센터 조회 화면
└─ 제로 ETL ──────► Redshift ──► 경영 대시보드
▲
S3 레이크(3년치 로그, Parquet·날짜 파티션) ──Spectrum──┘ Athena ──► 데이터 과학자의 애드혹 분석
지점 선택 이유 흔한 오답 장바구니 DynamoDB 온디맨드 사용자 ID 로 밀리초 조회, 이벤트 때 트래픽 급증 Aurora(급증 대응이 어렵다) 주문·결제 Aurora 여러 테이블에 걸친 트랜잭션, 정합성 DynamoDB(조인·복잡한 트랜잭션에 부적합) 고객센터 조회 Aurora 리더 같은 스키마 그대로, 라이터 보호 Redshift(건당 조회에 과함) 경영 대시보드 제로 ETL → Redshift 수억 행 집계, 파이프라인 관리 없음 리더에서 직접 집계(행 기반이라 느림) 3년치 로그 S3 + Spectrum 가끔 조회하는 대용량은 적재하지 않는다 전부 Redshift 에 적재(스토리지·적재 비용) 애드혹 분석 Athena 간헐적, 클러스터 불필요 전용 Redshift 클러스터 DynamoDB 변경 적재 Kinesis Data Streams → Firehose 코드 없이 S3 에 지속 적재, 장기 보존 주기적 Scan(운영 용량 소모)
대시보드가 아침 9시에 몰리면 Redshift 에 동시성 스케일링을 켠다. 하루 한 번의 짧은 피크는 무료 크레딧 안에서 끝나는 경우가 많다.
Redshift 의 주문 팩트 테이블은 고객 차원과 자주 조인하므로 customer_id 를 DISTKEY 로, 날짜 범위 조회가 많으므로 주문일을 정렬 키 첫 컬럼으로 둔다. 작은 지역 차원은 ALL 이다.
데이터 과학자의 Athena 워크그룹에는 쿼리당 스캔 한도를 걸어 실수로 3년치를 전부 읽는 쿼리를 막는다.
DynamoDB 를 리포트 DB 로 쓴다 : Scan 과 필터로 집계하며 읽기 용량을 태운다. export·스트림으로 내보낸다.
집계 축마다 GSI 를 추가한다 : 쓰기 비용만 늘고 집계는 여전히 못 한다.
Aurora 라이터에서 월말 정산 쿼리를 돌린다 : 트랜잭션이 느려진다. 리더 또는 Redshift 로 옮긴다.
모든 테이블에 DISTSTYLE ALL : 저장량과 적재 시간이 노드 수만큼 곱해진다.
조인 키와 무관하게, 혹은 편향된 컬럼을 DISTKEY 로 : 재분배 또는 스큐.
Redshift 에 단건 INSERT 를 반복한다 : COPY 로 묶어 적재한다.
Athena 에서 CSV 를 그대로 SELECT * : 가장 비싼 조합이다.
가끔 쓰는 분석을 위해 프로비저닝 클러스터를 상시 가동 : Athena 나 Redshift Serverless 가 맞다.
페더레이션 쿼리로 운영 DB 를 매시간 대량 조회 : 운영 부하가 쌓인다. 복제로 바꾼다.
시나리오 정답 S3 데이터를 인프라 없이 가끔 SQL 로 분석 Athena 두 대형 테이블을 같은 키로 자주 조인, 재분배 제거 양쪽 모두 그 컬럼을 DISTKEY 작은 차원 테이블의 조인 최적화 DISTSTYLE ALL 날짜 범위 조회가 느리다(Redshift) 날짜를 정렬 키로 아침마다 Redshift 쿼리가 큐에서 대기 동시성 스케일링 웨어하우스 데이터와 S3 의 오래된 이력을 함께 조회 Redshift Spectrum Athena 비용이 높다 파티션 + Parquet + 압축 + 필요한 컬럼만 Athena 파티션 수만 개, 메타데이터 조회 병목 파티션 프로젝션 팀별 Athena 비용 통제 워크그룹 + 쿼리당 스캔 한도 S3 와 RDS 를 데이터 이동 없이 조인 Athena 페더레이션 쿼리 DynamoDB 의 운영 데이터를 대규모 집계 export·스트림으로 S3/Redshift 에 옮겨 분석 DynamoDB 테이블에 부하 없이 전체를 분석 S3 export(PITR) DynamoDB 변경에 실시간 반응 Streams + Lambda Aurora 를 Redshift 에서 거의 실시간, 파이프라인 없이 제로 ETL Oracle → Aurora 이전 + 지속 복제 DMS 운영 DB 의 리포팅 부하를 가장 먼저 줄이는 방법 Read Replica 간헐적 웨어하우스 워크로드, 운영 최소화 Redshift Serverless
다음 주는 파이프라인을 지켜보는 쪽, CloudWatch 지표·로그·알람을 이용한 모니터링으로 넘어간다.
읽기 패턴 : 워크로드가 데이터를 읽는 방식. 건별 조회인지, 범위 집계인지, 검색인지가 스토어를 가른다.
과금 단위 : 서비스가 요금을 매기는 기준. 스캔량, 컴퓨팅 시간, 요청 단위 등이 있다.
쏠림(스큐·핫 파티션) : 분산 기준이 되는 키의 값이 편향되어 일부 노드·파티션에만 부하가 몰리는 현상.
건너뛰기(data skipping) : 통계나 경로 구조를 이용해 조건에 맞지 않는 데이터를 아예 읽지 않는 최적화.
레이크하우스 : 웨어하우스의 테이블과 S3 레이크의 데이터를 함께 조회하는 구성.
CQRS : 쓰기·건별 조회와 분석·집계를 서로 다른 스토어에 맡기는 분리 패턴.
신선도(freshness) : 원천에서 바뀐 값이 분석 쪽에 보일 때까지 걸리는 시간.
팩트 테이블 / 차원 테이블 : 측정값이 쌓이는 큰 테이블과, 그것을 설명하는 작은 기준 테이블.
📝 연습 문제 선택지를 클릭하면 정답·해설이 펼쳐집니다.
"S3에 쌓인 데이터를 인프라 프로비저닝 없이 간헐적으로 표준 SQL로 분석"하려는 요구에 가장 적합한 서비스는?
A Amazon Redshift (프로비저닝 클러스터) B Amazon Athena C Amazon Aurora D Amazon DynamoDB Redshift에서 두 대형 팩트/차원 테이블을 동일 키로 자주 조인할 때 재분배를 피하는 최적 설정은?
A 두 테이블 모두 동일 컬럼을 DISTKEY로 지정 B 두 테이블 모두 DISTSTYLE EVEN C 두 테이블 모두 INTERLEAVED SORTKEY D 한 테이블만 DISTSTYLE ALL (둘 다 대형) DynamoDB에 저장된 운영 데이터를 대규모로 집계·리포팅해야 한다. 권장 접근은?
A DynamoDB에서 풀 스캔으로 직접 집계 B GSI를 수십 개 만들어 모든 집계를 인덱스로 처리 C Streams/S3 export로 S3·Redshift에 옮겨 Athena/Redshift로 분석 D LSI를 추가해 집계 전용 축을 만든다 Aurora의 운영 데이터를 ETL 파이프라인 운영 부담 없이 Redshift에서 거의 실시간으로 분석하려면?
A AWS DMS로 매시간 배치 마이그레이션 B 제로 ETL(Zero-ETL) 통합 C Athena 페더레이션 쿼리 D Redshift Spectrum 외부 스키마 Athena에서 파티션이 수만 개로 늘어 카탈로그 조회와 MSCK REPAIR가 병목이 될 때 가장 적절한 해결책은?
A 동시성 스케일링 활성화 B DISTSTYLE ALL 적용 C 파티션 프로젝션(Partition Projection) D 모든 파일을 CSV로 변환