Show HN: Streambed – S3의 Iceberg로 Postgres 스트리밍, Postgres Wire 지원
출처: Hacker News
Postgres‑to‑Iceberg CDC 엔진. 애플리케이션을 변경하지 않고도 운영 데이터베이스에서 분석 쿼리를 오프로드합니다.
streambed는 논리 복제를 통해 WAL 변화를 스트리밍하고, Parquet 파일을 S3에 쓰며 Iceberg 메타데이터를 커밋합니다. 결과는 Iceberg‑호환 엔진으로 조회하거나, psql 로 연결할 수 있는 Postgres 와이어 프로토콜을 지원하는 내장 쿼리 서버를 사용할 수 있습니다.
실제 동작 보기
같은 분석 쿼리를 pgbench(1 M 계정, 500 K 히스토리 행)에서 실행했습니다. 왼쪽은 Postgres, 오른쪽은 Streambed입니다.
ETL 없이. Spark 없이. Postgres + S3 만으로.
빠른 시작
로컬에서 Postgres + MinIO 시작
docker compose up -d
빌드
go build -o streambed ./cmd/streambed
:5433 에서 동기화 + 쿼리 서버 시작
./streambed sync \
--source-url="postgres://postgres:test@localhost:5432/postgres" \
--s3-bucket="streambed" \
--s3-endpoint="http://localhost:9000" \
--s3-prefix="test" \
--query-addr=:5433
Iceberg을 통해 Postgres 테이블 조회
psql -h localhost -p 5433 -U postgres -d postgres
전체 설정 옵션을 보려면 streambed sync --help 를 실행하세요. 모든 플래그는 STREAMBED_ 접두사가 붙은 환경 변수도 지원합니다(예: STREAMBED_SOURCE_URL).
아키텍처
작동 원리
Postgres WAL ──▶ Decode ──▶ Buffer ──▶ Parquet ──▶ S3 ──▶ Iceberg Commit
│
DuckDB ◀──┘ (query server)
Streambed는 논리 복제 구독자로 Postgres에 연결합니다. WAL 메시지(INSERT, UPDATE, DELETE)를 디코딩하고, 테이블별로 행을 버퍼링한 뒤 주기적으로 Parquet 파일로 S3에 저장하고 Iceberg 메타데이터를 커밋합니다. UPDATE와 DELETE는 기존 Parquet 데이터에 대해 copy‑on‑write 방식으로 병합됩니다.
쿼리 서버는 내장 DuckDB를 이용해 Iceberg 테이블을 Postgres 와이어 프로토콜로 노출하므로 psql 이나 다른 Postgres 클라이언트로 조회할 수 있습니다.
명령어
| 명령어 | 설명 |
|---|---|
streambed sync | 메인 데몬. WAL을 스트리밍하고 Iceberg에 기록하며, 옵션으로 쿼리 서비스를 제공합니다. |
streambed resync --table=public.users | 일관된 스냅샷 아래 COPY 로 한 번에 백필합니다. |
streambed query | 동기화 없이 독립적인 쿼리 서버. 기존 Iceberg 테이블을 대상으로 합니다. |
streambed cleanup --table=public.users | 해당 테이블의 S3 객체와 상태를 삭제합니다. resync 전용으로 유용합니다. |
개발
Go 1.22 이상과 CGO( go‑duckdb, go‑sqlite3 사용을 위해 )가 필요합니다.
빌드
go build -o streambed ./cmd/streambed
단위 테스트
go test ./internal/... ./config/...
통합 테스트 (Docker 필요)
./scripts/test-integration.sh
통합 테스트는 integration 빌드 태그를 사용하며 test/integration/docker-compose.yml 에 정의된 Postgres(포트 5434)와 MinIO(포트 9002) 환경에서 실행됩니다.
