ETL for Rental apartments using Step functions, AWS Glue and Redshift
에어비앤비와 유사한 임대 아파트 플랫폼의 데이터를 분석하기 위해, 비용 효율적인 데이터 웨어하우스를 구축
사용되는 핵심 AWS 기술 스택
- 데이터 소스: AWS Aurora(MySQL) — 원본 애플리케이션 데이터베이스
- 스토리지(데이터 추출용): Amazon S3
- ETL 작업: AWS Glue (Python Shell) — 데이터 추출, 변환, 적재
- 데이터 웨어하우스: Amazon Redshift — 분석 및 리포팅용
- 오케스트레이션: AWS Step Functions — 전체 파이프라인의 작업 순서 제어 및 자동화(기존 Airflow를 대체하는 역할)
Redshift 데이터 레이어 구조
데이터 웨어하우스 내에서 데이터는 다음 3단계를 거쳐 목적에 맞게 정제됨
- Raw Layer(원시 데이터): 소스에서 가져온 데이터를 아무런 변경 없이 있는 그대로 저장하는 계층
- Curated Layer(가공 데이터): 데이터 모델링 기법을 적용하여 데이터를 가공하고 정제하는 계층
- Presentation Layer(프레젠테이션 데이터): 비즈니스 사용자가 리포팅에 바로 활용할 수 있도록 계산된 최종 비즈니스 지표가 저장되는 계층
파이프라인 전체 흐름(Step Functions로 제어)
총 4개의 Glue Python Shell Job이 순차적으로 실행되며 전체 파이프라인을 구성
- Job1: MySQL DB에 연결하여 데이터를 추출한 뒤 S3 버킷에 저장
- Job2: S3에 추출된 데이터를 읽어와 Redshift의 Raw Layer로 복사(ingestion)
- Job3: Raw Layer의 데이터를 가공하여 Curated Layer로 적재
- Job4: Curated Layer의 데이터를 바탕으로 비즈니스 지표를 계산하여 Presentation Layer로 최종 적재
🟢 데이터 웨어하우스 구축할 때 고려해야 하는 점
- efficiency and reliability
- cost
- simplest solution is the best
AWS Step Functions
- serverless orchestration tool
- 서버 프로그래밍이나 인프라 관리 없이 Lambda, S3, Glue, EMR 등 다양한 AWS 서비스들을 연결해 워크플로우를 자동화하고 순차적으로 실행
- workflow 수요에 맞춰 자동으로 확장(auto-scaling) 되는 것이 특징
Step Functions vs Apache Airflow
두 기술 모두 파이프라인의 작업 순서를 제어하는 오케스트레이션 역할을 함
- Step Functions
인프라&비용: 완전 서버리스. 미리 설정하거나 관리할 서버(인프라)가 없으며, 사용한 만큼만 비용을 지불개발 방식: low-code 또는 no-code. json이나 웹 콘솔로 흐름만 정의하며, 각 단계에서 다른 서비스를 트리거하는 데 집준적합한 경우: 파이프라인이 가끔 실행되거나, 자주 실행되더라도 단계와 단계 사이를 넘어갈 때 복잡한 로직이 필요 없는 경우에 유리
- Airflow(복잡한 제어와 확장성에 초점)
인프라&비용: 초기 환경 설정(노드 수, vCore 등 지정)이 필수적. 파이프라인(DAG)이 하나도 실행되지 않고 쉬는 상태여도 기본 인프라 유지 비용이 발생개발 방식: python 코드로 직접 애플리케이션 로직을 작성하고, 런타임에 필요한 라이브러리를 설치하거나 데이터를 직접 변환할 수 있음적합한 경우: python 코딩을 통해 세밀한 제어가 필요한 아주 복잡한 워크로드에 더 적합
AWS Aurora for MySQL
확장성: 트래픽이나 워크로드가 증가하더라도 application code를 수정할 필요 없이 scale-up하여 대응 가능
고가용성 및 내구성: 3개의 Availability Zones 에 데이터를 복제하여 저장하므로, 시스템 장애가 발생해도 데이터 유실 위험이 적고 안정성이 뛰어남
완벽한 MySQL 호환성: 기존에 MySQL을 사용하던 애플리케이션이라면 코드를 단 한 줄도 수정하지 않고 그래도 Aurora로 마이그레이션하여 사용 가능
Setup MySQL db on AWS Aurora
데이터 적재
- 엔드포인트 복사: 생성된 DB 상세 페이지의 Connectivity & security 탭에서 Writer Instance의 엔드포인트 주소를 복사.
- 보안 그룹 이동: 해당 페이지 하단의 VPC security groups 링크를 클릭하여 새 탭에서 열기.
- 인바운드 규칙 편집:
- 해당 보안 그룹 ID 클릭 -> Inbound rules -> Edit inbound rules 클릭.
- Add rule 클릭.
- Type: MySQL/Aurora 선택 (포트 3306 자동 입력).
- Source:
0.0.0.0/0선택 (모든 IP 허용, 실습 목적). - Save rules 클릭하여 저장.
sql(3개의 테이블 apartments, apartment_attributes, apartment_viewings 생성 및 데이터 적재)
Deploy and execute my MySQL Extraction Glue Job
- 추출 전략
- 증분 로드(incremental load): 데이터가 큰 트랜잭션 테이블용. 마지막으로 자겨온 지점 이후의 데이터만 추출
- 전체 로드(full load): 크기가 작은 비트랜잭션 테이블용. 매번 전체 테이블 추출
데이터 추출은 테이블의 성격에 따라 두 가지 방식으로 나뉨
사전 준비: DynamoDB
incremental load를 위해서는 “어디까지 읽었는지” 기록할 장소가 필요하며, 여기서는 DynamoDB를 사용
- 테이블 생성:
- 이름:
Incremental_Load_Configurations - 파티션 키:
table_name(String)
- 데이터 초기화 (
write_to_dynamo.py실행): - 로컬에서
python write_to_dynamo.py를 실행하여 3개 테이블의 설정값을 주입합니다. - 결과:
apartments:last_modified_timestamp기준 증분 추출 (초깃값 Null)apartment_viewings:viewed_at기준 증분 추출 (초깃값 Null)apartment_attributes: 증분 컬럼 없음 (Full Load 대상)
dynamodb에 제대로 적재됨
보안설정: AWS Secrets Manager
DB 비밀번호를 코드에 노출하지 않기 위해 사용
- 새 비밀번호 저장: 'Credentials for Amazon RDS database' 선택.
- 정보 입력: Aurora 생성 시 설정한
admin계정과 비밀번호 입력.
- 대상 선택: 이전에 생성한
rental-apartments-db를 선택.
- 비밀번호 이름:
Rental_DB로 명명.
- AWS Glue Job 생성
- 핵심 함수 로직
get_RDS_credentials: Secrets Manager에서 JSON 형태로 자격 증명을 가져와 파싱fetch_configuration: DynamoDB에서 해당 테이블의 증분 기준 컬럼명과 마지막 추출 값을 읽어오기update_last_extracted_value: 추출 성공 후, 가장 최신 데이터의 타임스탬프를 DynamoDB에 업데이트하여 다음 실행 때 중복 방지- 메인 쿼리 로직
- Full Load:
SELECT * FROM [table_name] - Incremental Load:
SELECT * FROM [table_name] WHERE [incremental_column] > [last_extracted_value] - 결과 저장: 추출된 데이터를 CSV로 변환하여 S3 경로(
s3://[bucket]/landing_zone/[table_name]/data.csv)에 업로드
Python Shell 타입의 Glue Job을 생성하고 스크립트 작성
- Glue Job 실행
- Job 이름:
MySQL_extraction_job - IAM Role: S3, DynamoDB, Secrets Manager, CloudWatch 접근 권한 필요
- Arguments 추가:
-table_name,-load_type - apartments:
-load_type incremental로 실행 → S3 파일 생성 및 DynamoDB 업데이트 확인 - apartment_viewings: 동일하게 실행
- apartment_attributes:
-load_type full로 실행 (증분 로직 없이 전체 추출) - S3:
landing_zone폴더 아래 각 테이블별로data.csv가 생성되었는지 확인 - DynamoDB:
last_extracted_value가null에서 실제 타임스탬프 값으로 변경되었는지 확인
Glue Job 구성
테이블별 실행
최종 확인
Deploy Redshift ingestion pipeline on AWS Glue
- Redshift 데이터베이스 및 계층 구조 설계
- Raw Zone: 소스 시스템(MySQL)의 데이터를 그대로 복제한 형태
- main tables: apartments, apartment_attributes, apartment_viewings
- temp tables: 데이터 병합(upsert)을 위해 임시로 데이터를 담는 클론 테이블(temp_ 접두사 사용)
- Process Zone: 분석에 최적화된 스타 스키마(star schema) 모델링을 적용한 계층
- 1개의 fact table: 수치 지표 저장
- 2개의 dimension table: 속성 정보 저장(정규화 통해 중복 제거)
데이터 웨어하우스 내부는 목적에 따라 두 개의 스키마로 분리됨
Redshift Serverless 생성
- 핵심 개념
- namespace: 데이터베이스, 사용자, 스토리지 등 데이터 자체가 담기는 논리적 컨테이너
- workgroup: 컴퓨팅 자원, vpc 네트워크 설정 등 데이터를 처리하는 힘을 담당
- 비용: 생성 자체는 무료, 쿼리를 실행할 때만 비용이 발생
- 생성
- 기본 설정 및 보안
- Customize Settings 선택: 기본 설정 대신 커스텀 설정을 선택
- Admin 자격 증명 설정: * 사용자 이름:
admin(기본값) - 비밀번호: 수동 설정 (나중에 파이프라인 연결 시 꼭 필요하므로 따로 메모하기)
- IAM 역할 생성: * S3 버킷 접근 권한을 포함한 IAM Role을 새로 생성하고 연결
- 워크 그룹 및 용량 설정
- Capacity (RPU) 선택: * 최소 단위인 8 RPU를 권장 (1 RPU당 16GB 메모리 제공)
- 강의 실습 수준의 워크로드에는 8 RPU로도 충분
- 네트워크 설정: * 기본 VPC와 보안 그룹을 선택하고, 사용 가능한 모든 서브넷을 지정
- 외부 연결을 위한 필수 추가 설정
- publicly accessible 설정
- 경로: Redshift 콘솔 > Workgroup 선택 > Data Access 탭
- 수정:
Edit버튼 클릭 후 Turn on publicly accessible 체크박스 활성화 및 저장 - 보안 그룹(security group) 인바운드 규칙 추가
- 포트 번호: 5439 (Redshift 기본 포트)
- 규칙: * Type: Redshift
- Port: 5439
- Source:
0.0.0.0/0(실습용이므로 모든 IP 허용)
생성 직후에는 외부(airflow나 파이썬 스크립트)에서 접근 불가. 이를 해결하기 위해 다음 두가지 설정 필요
- Redshift 환경 구축 (DDL 실행)
- 데이터베이스 생성:
DB_Rental_Apartments생성 - 스키마 생성:
raw_zone과process_zone스키마 각각 생성 - 테이블 생성: *
raw_zone에 메인 테이블 3개와 임시(temp) 테이블 3개 생성 (총 6개) process_zone에 스타 스키마 기반 테이블 생성
redshift에 schema, table 생성
보안 및 권한 설정(Secrets Manager & IAM)
- Secrets Manager 설정
DW_credentials라는 이름으로 Redshift 접속 정보(사용자, 암호, 엔드포인트) 저장- 중요: 생성 후 'Plaintext' 편집 모드에서 데이터베이스 이름을 기본값(
dev)에서 실습용 이름(DB_Rental_Apartments)으로 반드시 수정하기
- IAM Role ARN 복사
- Redshift Namespace의 Security and Encryption 탭에서 Redshift가 S3에 접근할 수 있도록 허용된 IAM Role의 ARN을 복사하여 스크립트에 반영
- Glue Ingestion Job 로직(redshift_raw_ingestion.py)
- COPY (s3 → temp table)
- MERGE (temp table → main table)
- TRUNCATE (temp table 비우기)
s3의 data.csv 데이터를 redshift로 옮기는 3단계 로직 수행
임시 테이블의 데이터를 메인 테이블과 비교하여, 새로운 데이터는 insert 하고 기존 데이터는 update 하는 upsert 작업 수행
- Glue Job 배포 및 실행
- Job 생성: AWS Glue에서 'Python Shell' 타입의 Job 생성
- 설정 변경: * Concurrency(동시성): 3으로 설정하여 3개의 테이블 작업을 동시에 실행 가능하도록 함
- Arguments:
-table_name파라미터를 통해 어떤 테이블을 처리할지 동적으로 지정 - 실행:
apartments,apartment_attributes,apartment_viewings각각에 대해 Job을 실행
Deploy pipeline to process curated data in Redshift on AWS Glue
- Process Layer의 설계 및 목적
- 데이터 모델링: 스타 스키마 적용 (1개의 Fact 테이블 + 2개의 Dimension 테이블)
- 구성 요소
dim_apartments: 아파트 정보 + 아파트 속성 정보를 조인(Join)하여 생성dim_users: 사용자 정보 차원fact_apartment_viewings: 아파트 조회 이력을 담은 사실(Fact) 테이블
Raw Layer가 소스 시스템의 복사본이었다면, Process Layer는 분석 효율성을 위해 구조를 변경한 단계
- 핵심: temp table 활용
- 특징: 세션(Session)이 유지되는 동안만 존재하며, Glue Job이 종료되면 자동으로 삭제됨
- 장점: 수십 개의 중간 단계 테이블을 영구적으로 관리해야 하는 번거로움을 줄여줌
- 저장 공간과 관리 오버헤드를 최적화 가능
- 흐름:
Raw 데이터 읽기→Temp Table 생성 및 데이터 삽입→Main Table로 Merge→세션 종료(삭제)
- 스크립트 주요 로직
- merge_dim_apartments
- raw_zone.apartments와 raw_zone.apartments_attributes를 join하여 아파트의 모든 세부 정보를 하나의 테이블로 합침
- 조인된 결과를 temp table에 먼저 넣고, 이를 최종 process_zone.dim_apartments에 merge
- merge_dim_users: 사용자 정보를 처리
- merge_fact_apartment_viewings(사실 테이블 & 증분 로드)
- 트랜잭션 데이터이므로 incremental load 방식 사용
- 로직
- get_last_processed_value 함수를 통해 현재 fact 테이블에 들어있는 가장 최신 타임스탬프를 가져옴
- raw layer에서 이 타임스탬프보다 크거나 같은 새로운 데이터만 필터링하여 temp table에 담기
- 새로운 데이터만 최종 fact 테이블로 머지
마찬가지로, AWS Glue Job 생성 하고 실행한다
- 결과 확인(Redshift Query Editor)
지금 까지 총 3개의 job 생성
Deploy Step functions to orchestrate workflow execution
핵심 개념: State Machine
Airflow의 DAG = Step Functions의 State Machine
Airflow의 Task = Step Functions의 State
JSON 형식의 정의서를 통해 어떤 작업을 먼저 할지, 성공하면 어디로 갈지, 마지막 작업은 무엇인지를 결정
- 워크플로우 설계(JSON 정의)
StartsAt: 워크플로우의 시작점 지정States- apartments 테이블 MySQL 추출
- apartments 테이블 Redshift Raw Ingestion
- 위 과정을 다른 테이블에 대해서도 반복 실행
- Redshift process layer ingestion job을 마지막으로 실행
json
AWS IAM Role 설정
Step Functions가 다른 서비스(Glue 등)를 대신 실행할 수 있도록 권한이 필요
- 역할 생성: IAM 콘솔에서
Step Functions서비스용 역할 생성
- 정책(Policy) 연결:
- AWSGlueConsoleFullAccess: Glue Job을 실행하기 위해 필요
- CloudWatchLogsFullAccess: 실행 로그를 기록하기 위해 필요
- 이름 지정:
Custom_StepFunctions_Role등으로 저장
state machine 생성 및 배포
- Step Functions 콘솔 접속: Create State Machine 클릭
- 템플릿 선택: Blank 템플릿 선택 후 Code 탭으로 이동
- 코드 붙여넣기: 준비된 JSON 정의서를 붙여넣고 시각화된 그래프가 의도대로 나오는지 확인
- 설정 구성: 생성한 IAM 역할을 연결하고 로그 레벨을
ALL로 설정하여 모니터링 준비 완료
Setup AWS Event Bridge for workflow scheduling and automation
워크플로우를 자동화한다!
Amazon EventBridge란?
다양한 소스의 애플리케이션을 연결해주는 서버리스 이벤트 버스 서비스
이벤트 기반 아키텍처의 핵심으로, 이벤트 라우팅부터 작업 예약(scheduling) 및 자동화까지 지원하며 거의 모든 AWS 서비스와 통합됨
scheduler 생성
기본 설정 및 이름 지정
- 서비스 접속: AWS 콘솔 검색창에 'EventBridge' 입력 후 선택
- 메뉴 선택: 왼쪽 메뉴에서 Scheduler → Create schedule 클릭
- 이름 지정: 스케줄의 목적을 알 수 있도록 명명 (예:
Schedule-step-functions-rental-DB)
schedule pattern 설정
- 스케줄 타입
| 타입 | 설명 | 예시 |
| Rate-based | 일정한 시간 간격마다 실행 | 6시간마다 실행 ( 6 hours) |
| Cron-based | 특정 시점(분, 시, 일 등)을 지정 | 매일 자정, 매주 월요일 등 |
- 대상 선택
- 서비스 선택: 스케줄러가 깨워야 할 대상인 Step Functions를 선택
- 워크플로우 지정: 이전 단계에서 만든
workflow-rental-apartments스테이트 머신을 선택
재시도 및 권한 설정
- Action after completion: 반복 작업이므로 작업 완료 후 스케줄을 삭제하지 않도록 None 선택
- Retry policy (재시도 정책): 실행 실패 시 다시 시도할 간격이나 횟수를 설정 (실습에서는 Off)
- Execution role (실행 역할): Create new role을 선택하면 EventBridge가 Step Functions를 실행할 수 있는 권한 정책을 자동으로 생성. 역할 이름은
EventBridge-step-functions-rental-role등으로 지정
scheduler 동작 확인
AWS 정리
- AWS Aurora DB 삭제
- EventBridge Scheduler 삭제
- Redshift Serverless namespace, workgroup 삭제
- step functions 삭제