Immersion In Data

Snowflake

[Snowflake] MSSQL에서 Snowflake까지, CDC 파이프라인 구축

sungjunminn 2025. 11. 4. 10:57

MSSQL의 데이터를 Snowflake로 실시간 동기화를 구축할 수 있는 방법을 공유합니다.

  1. MSSQL의 변경 데이터를 실시간으로 Snowflake에 반영할 수 있는가?
  2. 기존 파이프라인보다 더 빠른 성능을 보여줄 수 있는가?
  3. 데이터를 다른 계정(Snowflake)과 간편하게 공유할 수 있는가?

결론부터 말씀드리면, "전부 가능했습니다." 이 글에서는 저희가 구축한 아키텍처부터 성능 테스트 결과, 그리고 Snowflake의  데이터 공유까지 전 과정을 공유합니다.

 

1. 아키텍처: AWS DMS와 Snowflake의 조합

저희는 "MSSQL → S3 → Snowflake"로 이어지는 실시간 CDC(Change Data Capture) 파이프라인을 구축했습니다. 전체 흐름은 4단계로 자동화됩니다.

1단계: 변경 데이터 캡처 (AWS DMS)

먼저, 운영 DB인 MSSQL에서 발생하는 모든 INSERT, UPDATE, DELETE 이벤트를 AWS DMS(Database Migration Service)로 실시간 캡처했습니다. DMS는 이 변경 데이터를 14개 테이블 각각에 대해 S3 버킷에 CSV 파일 형태로 쌓아줍니다.

2단계: 자동 수집 (Snowpipe)

S3에 쌓인 CSV 파일을 옮기는 작업은 Snowpipe가 담당합니다. Snowpipe는 S3 버킷을 감시하다가 새 파일이 도착하면, 알아서 데이터를 Snowflake의 임시 CDC 테이블(테이블명_CDC)로 수집합니다. 

3단계: 변경분 추적 및 병합 (Stream & Task)

  1. Stream (스트림): 테이블명_CDC에 붙어서, Snowpipe가 가져온 '새로운 변경분'만 실시간으로 추적합니다.
  2. Task (태스크): 1분마다 주기적으로 실행되며 Stream에 새 데이터가 있는지를 확인합니다.
  3. MERGE (병합): Task는 Stream에 데이터가 있으면, MERGE 명령어를 실행하여 최종 목적 테이블에 데이터를 반영합니다.

4단계: 최종 데이터 정합성 (MERGE 로직)

MERGE 명령어는 Stream에 기록된 OP 컬럼(I, U, D)을 기준으로 지능적으로 동작합니다.

  • Insert (I) → 최종 테이블에 새 데이터 INSERT
  • Update (U) → PK가 동일한 데이터 UPDATE
  • Delete (D) → PK가 동일한 데이터 DELETE

이 구조를 통해, MSSQL과 거의 동일한 상태를 유지하는 최종 테이블을 Snowflake에 확보할 수 있었습니다.

 

2. 성능

초기 적재 (Initial Load)

DMS가 처음 실행되면 LOAD0001.csv 같은 대용량 초기 적재 파일이 S3에 떨어집니다. 이 파일들을 Snowflake로 적재하는 시간을 측정해 보았습니다.

결과는? Snowflake에서 가장 작은 XSMALL 웨어하우스를 사용했음에도 불구하고, 수백만 건의 데이터를 S3에서 Snowflake 테이블로 적재하는 데 걸린 시간은 단 몇 분에 불과했습니다. (모든 작업 내역은 Monitoring - Query History 메뉴에서 Query ID로 확인 가능했습니다.)

성능 테스트 

"기존 MySQL 파이프라인보다 얼마나 빠를까?"라는 질문에 답하기 위해 동일한 조건의 테스트를 진행했습니다.

  • 테스트 1: RoundRawT 테이블에 7만 건 INSERT → 1.1초 소요 (XSMALL)
  • 테스트 2: 1,000만 건의 RoundRawT 테이블을 조회하여 2개의 다른 테이블을 생성 (기존 MySQL 파이프라인 로직) → 수 초 내 완료

기존에 수십 분 걸리던 작업을 Snowflake Task로 동일하게 구성했음에도, 비교할 수 없을 만큼 빠른 속도를 보여주었습니다.

 

3. 데이터 공유(Data Sharing)

다른 Snowflake 계정과 데이터를 쉽게 공유하려면 Snowflake의 Data Sharing 기능을 활용하면 쉽게 해결할 수 있습니다. 

데이터 공유는 데이터를 물리적으로 복사(ETL)하지 않고, 다른 계정에 실시간 읽기 전용 접근 권한을 부여하는 방식입니다.

1. Data Sharing (소비자도 Snowflake 계정이 있을 때)

  • Provider (공급자): 공유할 테이블을 SHARE라는 객체에 담아 공유합니다. 데이터를 공유하는 행위 자체는 메타데이터 작업일 뿐이라 비용이 0입니다.
  • Consumer (소비자): 공유받은 데이터를 마치 자기 계정의 테이블처럼 즉시 조회합니다.
  • 비용 구조: 소비자가 데이터를 조회(Query)할 때, 소비자 본인의 웨어하우스를 사용합니다. 즉, 각자 사용한 만큼만 비용을 냅니다.

장점: 데이터 복제/이동/지연이 없습니다. Provider가 원본을 업데이트하면 Consumer에게 즉시 반영됩니다.

2. Reader Accounts (소비자가 Snowflake 계정이 없을 때)

"만약 공유하고 싶은 대상이 Snowflake 계정이 없으면 어떡하죠?"

이때 Reader Account를 사용합니다.

  • Provider (공급자): Snowflake 계정이 없는 파트너를 위해 읽기 전용의 무료 '독자 계정'을 생성하여 공유합니다.
  • Consumer (소비자): 이 계정으로 로그인하여 데이터를 실시간으로 조회합니다.
  • 비용 구조: 독자 계정은 컴퓨팅 자원이 없으므로, 소비자가 데이터를 조회할 때 발생하는 컴퓨팅 비용은 Provider(공급자)가 부담합니다.

장점: FTP나 이메일로 데이터를 전송하는 것보다 100배 안전하며, 파트너는 최신 데이터를 실시간으로 볼 수 있습니다.

비교 Data Sharing (표준) Reader Account (독자 계정)
소비자 계정 Snowflake 계정 필요 Snowflake 계정 불필요
조회 비용 부담 소비자 (본인 웨어하우스) 공급자 (공급자 웨어하우스)
주 사용처 사내 부서, 계열사 외부 파트너, 고객사

 

4. 결론

  1. 아키텍처: DMS, S3, Snowpipe, Stream, Task를 연동하여 안정적인 실시간 CDC 파이프라인을 구축했습니다.
  2. 성능: XSMALL 웨어하우스로도 기존 MySQL 파이프라인을 압도하는 성능을 증명했습니다.
  3. 공유: 데이터 복제 없이도 데이터를 실시간으로 안전하게 공유할 수 있는 것을 확인했습니다.