TECH 으로 돌아가기
TECH HACKER NEWS 오늘 8분 읽기 46 READS

스노우플레이크가 다시 짠 Postgres 복제: 푸시 기반 CDC의 설계

스노우플레이크가 다시 짠 Postgres 복제: 푸시 기반 CDC의 설계
SOURCE IMAGE · HACKER NEWS

운영 데이터베이스의 데이터를 분석 시스템으로 옮기는 일은 현대 데이터 아키텍처의 필수 과제이지만, 동시에 깨지기 쉬운 도구와 높은 비용, 복잡한 운영과의 끝없는 싸움이기도 하다. 스노우플레이크는 자사의 Postgres 서비스를 만들면서 이 문제를 최우선 과제로 삼았고, 그 결과물로 '데이터 미러링(data mirroring)'이라는 기능을 퍼블릭 프리뷰로 내놓았다. 핵심 메시지는 간단하다. Postgres 복제를 기존 도구 위에 얹는 대신 밑바닥부터 다시 설계했다는 것이다.

기존 CDC가 취약했던 이유

변경 데이터 캡처(CDC)는 트랜잭션 데이터베이스의 변경분을 다른 시스템에서 재생할 수 있는 형태로 잡아내는 작업이다. Postgres에서 이를 담당하는 기본 수단은 '로지컬 디코딩'으로, WAL 레코드를 행 단위의 삽입·수정·삭제 연산으로 해석해 네트워크 스트림으로 노출한다. 문제는 그 이후부터 모든 부담이 클라이언트에게 넘어간다는 점이다. 백필, 스키마 변경, 테이블 생성·삭제, 신규 테이블 스냅숏, 실패 후 재시작, 변경분 병합, 트랜잭션 경계 보존 같은 일들을 외부 도구가 떠안게 된다.

더 근본적인 한계는 변경분을 소비하는 외부 시스템이 Postgres의 상태를 전혀 알지 못한다는 데 있다. 스키마 변경이 언제 일어났는지, 스냅숏과 변경분이 어떻게 정렬되는지, 심지어 Postgres가 살아 있는지 아니면 네트워크가 끊긴 것인지조차 구분하기 어렵다. 이런 무지가 파이프라인을 취약하게 만드는 원인이다.

오브젝트 스토리지로 밀어 넣는 발상

스노우플레이크의 해법은 변경분을 Postgres에서 데이터 레이크로 '밀어 넣는' 것이다. 구체적으로는 압축된 Parquet를 담은 Apache Iceberg 테이블로 변경 배치를 보낸다. Amazon S3 같은 오브젝트 스토어는 확장성과 신뢰성이 높고 이미 Postgres 백업 용도로 널리 쓰이고 있으니, CDC의 목적지로도 적합하다는 논리다. 이를 위해 snowflake_cdc라는 새로운 Postgres 익스텐션이 백그라운드에서 테이블별 변경 로그와 '메타 로그'에 배치를 지속적으로 축적한다.

익스텐션 방식의 이점은 데이터베이스 내부에서 무슨 일이 벌어지는지 정확히 안다는 데 있다. 스키마 변경과 복잡한 DML·DDL 트랜잭션을 세밀하게 조율할 수 있고, 변경분을 계속 밀어 넣으면서도 스냅숏을 뜨고 그 스냅숏을 변경분과 정렬할 수 있다. 이렇게 producer와 consumer를 오브젝트 스토리지를 통해 분리하면, 뒤처질 수 있는 외부 커넥터라는 문제 자체가 사라진다.

양쪽 모두 트랜잭션으로 묶기

미러링의 데이터 흐름은 쓰기 → 디코딩 → 캡처 → 적용의 네 단계로 이어진다. 디코더는 Postgres의 '역사적 스냅숏' 기능으로 쓰기 시점의 카탈로그를 참조해, 이미 변경되거나 삭제된 테이블의 WAL 레코드도 올바른 논리 변경으로 해석한다. 주기적으로 배치가 확정되면 캡처 프로세스가 이를 Iceberg 변경 로그에 덧붙이고 메타 로그에 기록하며 복제된 LSN을 추적한다. 스노우플레이크 쪽의 적용 프로세스는 메타 로그의 지시를 실행하는 유한 상태 기계처럼 동작한다.

이 설계의 중심에는 트랜잭션이라는 원시 개념이 있다. 시스템이나 하드웨어 장애의 복잡성을 감추는 가장 단순한 수단이 트랜잭션인데, 기존 ETL·CDC의 고통은 바로 이 트랜잭션이 시스템 경계를 넘는 순간 사라지기 때문에 생긴다. 미러링은 Postgres 쪽에서 여러 변경 로그로의 푸시를 하나의 트랜잭션으로 묶고, 스노우플레이크 쪽에서도 여러 배치를 하나의 트랜잭션으로 병합한다. 그 결과 모든 스노우플레이크 테이블이 정확히 Postgres 트랜잭션 경계에 맞춰 함께 전진하므로 외래 키와 조인 정합성이 보존된다. 이 기반에는 Postgres 테이블과 Iceberg 테이블에 걸친 트랜잭션을 가능케 하는 pg_lake 익스텐션이 깔려 있다.

트랜잭션 제어는 정확성 측면에서도 이점을 준다. 흔한 복제 방식은 모든 연산을 upsert로 바꾸는데, 이는 스냅숏과 변경분 사이의 일관성 문제와 실패 후 중복 재생을 회피하기 위한 고육책이다. 반면 Postgres에서 트랜잭션으로 통제하면 삽입이 이미 스냅숏이나 다른 배치에 나타났을 위험 없이, 정확히 한 번만 적용되는 완결된 삭제·삽입 스트림을 만들 수 있다. 여기에 '라이브 뷰(live view)' 기능이 더해진다. 아직 적용되지 않은 변경 로그를 대상 테이블과 결합해 보여주되 필터와 프로젝션을 스토리지 계층까지 밀어내므로 빠르다. 덕분에 변경분을 자주 적용하지 않아도 지연이 1분을 크게 밑돈다.

실무자가 짚어야 할 지점

한국의 데이터 엔지니어 입장에서 이 발표는 두 가지 시사점을 준다. 첫째, 복제 아키텍처의 무게중심이 별도 커넥터나 스트리밍 인프라에서 오브젝트 스토리지 기반의 '푸시'로 옮겨갈 수 있다는 점이다. 유지해야 할 별도 시스템이 줄면 운영 부담과 비용 구조가 달라진다. 둘째, 소스와 타깃 양쪽을 한 벤더가 쥐고 있어야 성립하는 설계라는 점도 분명하다. 익스텐션이 Postgres 내부를 훤히 들여다보고 Iceberg·스노우플레이크가 이를 트랜잭션으로 받는 구조는, 바꿔 말하면 스노우플레이크가 관리하는 Postgres라는 조건에 강하게 묶여 있다.

또한 현재 상태가 퍼블릭 프리뷰라는 점, 그리고 이 글이 벤더의 엔지니어링 블로그를 바탕으로 한 설계 설명이라는 점은 감안해야 한다. 원문은 처리량이나 지연에 대한 구체적 벤치마크 수치 대신 '1분 미만' 같은 정성적 표현과 아키텍처 원리를 제시할 뿐이다. WAL이 유실되는 예외 상황에서는 새 스냅숏을 다시 밀어 넣는 경로가 있으나 페일오버 슬롯 덕분에 드물다는 설명처럼, 실패 모드에 대한 검증은 실제 워크로드에서 각자 확인해야 할 몫이다. 그럼에도 복제를 '혼돈스러운 프로세스'에서 '스위스 시계'로 바꾸려는 문제의식 자체는, 여전히 취약한 파이프라인과 씨름 중인 팀이라면 참고할 만한 설계 관점이다.

SOURCE · HACKER NEWS
원문 전체 보기 → https://www.snowflake.com/en/blog/engineering/postgres-to-sn...
SHARE
처리 중...