LLM WikiAccess-protected knowledge portal

WIKI

Glue·PySpark Full Load: 운영 DB를 보호하며 수십억 행 옮기기

대량 이관의 첫 목표는 속도가 아니라 영향 격리다 수십억 행을 운영 Aurora MySQL에서 직접 읽으면 버퍼 풀, 스토리지 I/O, network, long transaction이 실제 서비스와 경쟁한다. 빠른 이관을 위해 운영 트랜잭션을 느리게 만들면 목적을 잃는다. 리멤버 공개 사례는 Full Load 전용 Aurora replica를 만들고, AWS Glue PySpark가 JDBC로 복제본을 병렬 스캔해 S3 Tab

경로human/study/content/remember-data-engineering/06-glue-pyspark-full-load.md
카테고리Study
태그#engineering #full #glue #infra #load #mysql #pyspark #study

대량 이관의 첫 목표는 속도가 아니라 영향 격리다

수십억 행을 운영 Aurora MySQL에서 직접 읽으면 버퍼 풀, 스토리지 I/O, network, long transaction이 실제 서비스와 경쟁한다. 빠른 이관을 위해 운영 트랜잭션을 느리게 만들면 목적을 잃는다.

리멤버 공개 사례는 Full Load 전용 Aurora replica를 만들고, AWS Glue PySpark가 JDBC로 복제본을 병렬 스캔해 S3 Tables에 쓰도록 구성했다. 운영 소스와 이관 워크로드를 먼저 분리한 뒤 병렬도를 올린 선택이다.

서비스Aurora writer
Full Load 전용 replica Glue PySpark JDBC partitions S3 Tables / Iceberg
전용 복제본을 이용한 Full Load

1. 전용 replica에서도 보아야 할 것

복제본은 운영 writer의 쿼리 자원과 읽기 부하를 분리한다. 그러나 무한한 복제본은 아니다.

따라서 replica를 만든 이후에도 CPU, Read IOPS, active connection, lag, long transaction을 같이 본다.

2. JDBC 병렬 읽기는 범위를 잘 나누는 문제다

Spark JDBC reader의 partitionColumn, lowerBound, upperBound, numPartitions는 동시 쿼리의 범위를 결정한다. 공개 사례는 테이블의 min/max ID를 구한 뒤 약 100만 건 단위로 처리하도록 파티션 수를 동적으로 조정했다.

이 방법의 함정은 아래와 같다.

3. 타입 변환은 행 수 보다 먼저 검증한다

MySQL과 Spark·Parquet는 타입 세부 의미가 다르다. 공개 사례는 다음 경계를 따로 다뤄다.

행 수가 같아도 타임존이나 패딩이 바뀌면 데이터 의미는 달라진다. 그래서 타입별 표본, min/max, NULL 수, 고유값 수를 함께 비교한다.

4. ‘끝남’의 증거

이관 완료 조건은 작업 상태 SUCCESS가 아니다.

  1. 전체 테이블 목록과 누락 테이블 0
  2. 테이블별 행 수·PK 집합 대조
  3. 핵심 컬럼의 NULL·min/max·hash 대조
  4. 샤드·파티션별 표본 검증
  5. Full Load 기준점 이후 CDC lag 소진
  6. downstream 주요 쿼리의 결과·성능 비교
  7. 재실행·중단·rollback 절차와 근거 보존

References