Blog/데이터 엔지니어링/Snowpipe Streaming으로 더 간편해진 Apache Iceberg 데이터 스트리밍
2026년 8월 25일/6분 읽음데이터 엔지니어링

Snowpipe Streaming으로 더 간편해진 Apache Iceberg 데이터 스트리밍

인프라 구축 부담 없이 진행하는 대규모 스트리밍 성능 평가

Snowpipe Streaming이 100만 TPS 이상의 처리량을 안정적으로 지원하는지 확인하려는 팀이라면, 실제 결과를 가장 빠르게 확인할 수 있는 방법이 필요합니다. 대규모로 스트리밍하는 워크로드는 구축하기 까다로운 것으로 악명이 높습니다. S3 버킷, EKS 클러스터, Kafka 토픽, IAM 정책, 보안 검토와 승인이 필요한 데다 각기 다른 백로그를 안고 있는 3개 플랫폼 팀의 승인까지 받아야 하기 때문에 많은 팀이 도입을 미루곤 합니다. 이러한 설정에는 테스트를 시작하기 전에 추가 인프라 프로비저닝과 조정 작업이 필요할 수 있습니다. 파이프라인이 프로덕션 규모의 데이터를 안정적으로 처리하는지 검증하는 작업 자체가 하나의 독립적인 프로젝트가 되는 경우도 많습니다.

Snowflake는 데모 환경에서 오후 한 나절이면 이러한 평가 환경을 구축하고 실행할 수 있었습니다. Snowpipe Streaming 고성능 아키텍처를 사용하면 Snowflake 인프라 내부에서만 100만 TPS 이상의 속도로 Apache Iceberg™ 형식에 데이터를 스트리밍할 수 있습니다. Snowpark Container Services(SPCS)에서 실행되는 컨테이너가 부하를 생성하고 SDK를 통해 스트리밍한 후 Snowflake 관리형 Iceberg 테이블에 적재합니다. 데이터는 적재되는 즉시 Snowflake에서 쿼리할 수 있으며 역할 기반 액세스 제어(RBAC), 데이터 계보 및 마스킹 정책도 곧바로 적용됩니다. Snowflake 테스트에서는 데모 환경 구축부터 엔드투엔드 검증, 처리량 측정, 환경 철거까지 모든 과정을 오후 한나절 만에 완료했습니다.

이 글에서는 이 GitHub 리포지토리를 사용해 Iceberg로 엔드투엔드 스트리밍 데모를 직접 구축하는 방법을 소개합니다. 이 예제는 Python으로 작성되었지만 SDK 옵션(Java, Python, Node, REST)을 원하는 대로 테스트할 수 있으므로, 실제 측정 결과를 근거로 해당 아키텍처의 도입을 비즈니스에 자신 있게 제안할 수 있습니다.

아키텍처 다이어그램: 구현 패턴

이번 데모는 모든 구성 요소가 Snowflake 인프라 내부에서 실행되도록 설계했습니다. Snowpark Container Services(SPCS)에서 실행되는 여러 Docker 컨테이너가 목표 초당 트랜잭션 수에 맞춰 합성 테스트 데이터를 생성하고 Snowpipe Streaming SDK를 사용해 스트리밍합니다. 데이터는 Snowflake 관리형 Iceberg 테이블에 저장됩니다. 개방형 형식이며, 데이터가 저장된 후 몇 초 내에 쿼리할 수 있고 Snowflake에서 거버넌스가 적용됩니다. 인증도 간단합니다. SPCS가 단기 유효 OAuth 토큰을 컨테이너에 주입하면 Streaming SDK가 해당 토큰을 인증에 사용합니다. 따라서 별도의 보안 정보를 직접 관리할 필요가 없습니다.

Snowflake architecture diagram showing SPCS Service load generator streaming data to Iceberg Table via Snowpipe
Figure 1: Snowpark Container Service to Iceberg

부하 생성에 SPCS를 사용하는 이유

Snowpipe Streaming을 사용하는 데 SPCS가 반드시 필요한 것은 아닙니다. SDK는 노트북, EC2 인스턴스, Kubernetes 파드 등 어디에서나 실행할 수 있습니다.

그럼에도 SPCS를 사용하면 테스트 환경을 더 빠르게 구축할 수 있습니다. 서비스 전체가 Snowflake에서 이미 관리하는 인프라에서 실행되므로, 테스트를 위해 새로운 리소스를 프로비저닝하거나 추가 승인을 받을 필요가 없기 때문입니다.

Iceberg에 직접 적재

데이터의 적재 대상은 Snowflake 관리형 Iceberg 테이블입니다. SDK를 통해 행 데이터가 스트리밍되고 Snowflake가 관리하는 Iceberg 메타데이터와 함께 Parquet 형식으로 저장됩니다. 이후 필요에 따라 자체 S3 외부 볼륨을 연결하거나, 평가가 끝난 후에도 관리형 구성을 그대로 유지할 수 있습니다. 어느 방식을 선택하더라도 코드는 변경할 필요가 없습니다.

평가 단계에서는 설정해야 할 항목이 줄어든다는 장점이 있습니다. Snowflake 관리형 스토리지에 테이블을 생성하면 외부 볼륨, 스토리지 통합, 클라우드 스토리지 권한을 사전에 구성할 필요가 없습니다.

프로덕션 환경으로 전환할 준비가 되면 다음 세 가지 경로 중에서 선택할 수 있습니다.

  • 외부 볼륨을 사용하는 Snowflake 관리형 Iceberg: Parquet 파일은 자체 S3 버킷에 저장됩니다. 외부 엔진은 메타데이터에 Horizon REST 카탈로그를 사용해 S3에서 Parquet 파일을 직접 읽습니다.
  • Snowflake 스토리지를 사용하는 Snowflake 관리형 Iceberg: 파일은 Snowflake 내부 스토리지에 저장됩니다. 이 옵션을 사용하면 외부 볼륨과 관련 클라우드 스토리지를 구성하지 않아도 됩니다. 향후 호환성을 위해 Iceberg 기능을 활용합니다.
  • 네이티브 Snowflake 테이블: 별도로 관리하는 외부 스토리지 인프라가 필요하지 않습니다.

데모: 실행 화면

Terminal output showing Snowpipe Streaming data ingestion progress from configuration through verification stages
Figure 2: Demo of end to end streaming

데모 스크립트를 실행하면 SPCS 서비스가 시작되고 프로듀서가 부하 생성을 시작하며, 컨슈머가 Iceberg 테이블로 데이터를 스트리밍하는 과정을 확인할 수 있습니다.

Snowsight에서도 행 수가 실시간으로 증가하는 모습을 확인할 수 있습니다. 수백만 건의 데이터가 적재되는 즉시 쿼리 가능한 상태로 제공됩니다.

코드: 직접 구축하기

전체 작동 방식을 이해할 수 있도록, 전체 흐름을 시각화할 수 있는 의사 코드를 살펴봅니다. 전체 코드는 GitHub 리포지토리에서 확인할 수 있으며, 아래에는 여러 대체 데모도 연결되어 있습니다.

먼저 Snowflake 관리형 Iceberg 테이블과 파이프를 생성합니다.

-- 1. The target table
CREATE OR REPLACE ICEBERG TABLE events (
    event_id STRING,
    event_ts TIMESTAMP_NTZ,
    payload  VARIANT
)
CATALOG = 'SNOWFLAKE'
BASE_LOCATION = 'events/'
ICEBERG_VERSION = 3;


-- 2. The streaming pipe (extracts typed fields from the SDK's VARIANT payload)
CREATE OR REPLACE PIPE events_pipe
AS COPY INTO events (event_id, event_ts, payload)
FROM (
    SELECT $1:event_id::STRING,
           $1:event_ts::TIMESTAMP_NTZ,
           $1:payload::VARIANT
    FROM TABLE(DATA_SOURCE(TYPE => 'STREAMING'))
);

Snowpipe Streaming의 고성능 아키텍처는 v2와 v3를 모두 지원하지만, 파라미터를 생략하면 테이블은 기본적으로 v2로 설정됩니다.

다음은 컨슈머입니다.

from snowflake.ingest.streaming import StreamingIngestClient


# SPCS injects credentials automatically - no keys, no secrets
props = {
    "account": "YOUR_ACCOUNT",
    "user": "YOUR_USER",
    "role": "STREAMING_SERVICE_ROLE",
    "url": "https://YOUR_ACCOUNT.snowflakecomputing.com",
    "authorization_type": "SPCS",
    "spcs_token_path": "/snowflake/session/token",
}


# Connect to the pipe
client = StreamingIngestClient(
    client_name="my_consumer",
    db_name="STREAMING_DEMO",
    schema_name="PUBLIC",
    pipe_name="events_pipe",
    properties=props,
)


# Open a channel and stream rows
channel, status = client.open_channel("ch_1")


for i, row in enumerate(generate_load()):
    channel.append_row(row, offset_token=str(i))


# Close cleanly
channel.close()
client.close()

그런 다음 간단한 서비스 사양으로 컨슈머를 SPCS에 배포합니다. 이제 데이터가 적재되는 과정을 확인합니다.

SELECT
COUNT(*) AS rows_landed,
MAX(event_ts) AS latest_event
FROM
streaming_demo.public.events;

Java, Node 및 REST 인터페이스도 동일한 방식으로 작동합니다. 채널을 열고, 행을 삽입한 다음, 플러시합니다. 리포지토리에는 각 환경에 맞는 실행 가능한 예제가 있으므로, 사용하는 스택에 맞는 예제로 테스트할 수 있습니다.

직접 실행해 보려면 리포지토리를 확인하세요.

단, Streaming SDK는 HTTPS를 통해 별도의 수집 엔드포인트를 사용합니다. 따라서 Snowflake 내부에서 실행하는 경우에도 *.snowflakecomputing.com으로 송신할 수 있도록 허용하는 외부 액세스 통합을 부여해야 합니다.

모범 사례

Snowpipe Streaming의 자동 배치 처리

Snowpipe Streaming은 행마다 개별 파일을 생성하지 않습니다. SDK는 appendRows를 호출하는 즉시 행을 전송하지만, 서버 측 버퍼링 계층이 이를 수용하고 자체적으로 커밋 시점을 결정합니다. 내부적으로 배치 처리하므로 행마다 파일을 전송할 필요가 없습니다.

게다가 Snowflake가 단독으로 데이터를 쓰는 Snowflake 관리형 Iceberg 테이블의 경우, Snowflake가 백그라운드에서 자동으로 압축을 수행합니다. 작은 Parquet 파일을 더 큰 파일로 병합하고, 작은 매니페스트도 압축합니다. 압축 시점을 예약하거나 직접 실행할 필요 없이 일반 운영 과정에 포함되어 자동으로 처리됩니다.

다음과 방법을 적용하면 스트리밍 효율을 더욱 높일 수 있습니다.

  • 클라이언트 측에서 행을 배치 처리한 후 appendRows를 호출합니다. 행을 한 번에 하나씩 전송하면 행마다 한 번의 왕복 통신이 발생합니다. 여러 행을 하나의 호출로 묶으면 이러한 오버헤드를 분산할 수 있습니다. 이는 요청별로 더 많은 데이터를 압축해 전송하도록 권장하는 Snowflake의 기본 원칙과도 일치합니다.
  • 채널을 장시간 유지합니다. 소스 파티션마다 채널을 한 번만 열고, 마이크로 배치마다 열고 닫는 대신 작업이 실행되는 동안 계속 열어 둡니다. 이는 Snowflake가 문서화한 모범 사례Snowpipe Streaming에 해당하며, 내부에서 이미 진행 중인 배치 처리를 방해하지 않으면서 오버헤드를 줄여 줍니다.
  • 테이블에 TARGET_FILE_SIZE 를 설정합니다. SDK와 독립적으로 적용되는 테이블 수준 속성으로, 데이터가 어떤 경로로 유입되었는지와 관계없이 새 쓰기와 백그라운드 압축에 적용할 목표 파일 크기를 Snowflake에 지정합니다.
  • 지속적인 처리량을 활용합니다. TPS가 높게 유지될수록 서버 측 버퍼가 더 빠르게 채워지고 자동으로 플러시됩니다. 그 결과 특정 파일 크기에서는 처리량과 지연 시간 사이에 상충 관계가 형성됩니다. 

앞으로의 변화: Iceberg v4

Snowpipe Streaming과 자동 압축은 물리적으로 작은 파일이 다수 생성되는 문제를 해결하지만, 잦은 커밋은 Iceberg 메타데이터 트리에 여전히 오버헤드를 발생시킬 수 있습니다. 현재는 커밋이 발생할 때마다 새로운 메타데이터 JSON, 매니페스트 목록 및 매니페스트가 생성됩니다. 파일이 작은 파일 하나뿐인 경우에도 마찬가지입니다. 몇 초마다 커밋하는 워크로드에서는 이러한 반복적인 메타데이터 작업이 병목이 될 수 있습니다.

Iceberg v4 제안은 이러한 쓰기 증폭을 줄이기 위해 Adaptive Metadata Tree를 도입합니다. 소규모 커밋마다 새로운 매니페스트를 만드는 대신, 루트 매니페스트에 해당 커밋을 직접 포함할 수 있습니다. 현재의 연쇄적인 메타데이터 갱신 작업을 한 번의 Parquet 쓰기와 원자적 포인터 전환으로 대체함으로써, 커밋당 메타데이터 I/O가 매니페스트 수에 따라 증가하지 않고 일정하게 유지됩니다. 고빈도 스트리밍 워크로드에서는 이를 통해 스트리밍 지연 시간을 크게 줄일 수 있습니다.

스트리밍은 Iceberg v4의 대표적인 활용 시나리오 중 하나입니다. 몇 초마다 커밋하는 워크로드에서는 메타데이터 쓰기 증폭 문제가 직접적으로 드러나므로 Adaptive Metadata Tree의 이점이 특히 크게 나타납니다. v4 사양은 아직 발전 중이지만 Iceberg 스트리밍을 로드맵에 포함하고 있다면 주목할 만합니다. Snowflake는 Iceberg 형식의 미래를 만들어 가는 과정에 적극적으로 참여하고 있습니다.

아키텍처 관점에서의 시사점

이 글에서는 Snowpipe Streaming을 활용해 Iceberg로 데이터를 스트리밍하는 방식이 얼마나 효과적인지 살펴봤습니다. 대규모 미디어 또는 통신 플랫폼에서 처리하는 수준의 부하를 대상으로 테스트했지만, 테스트 환경을 위해 S3 버킷, EKS 클러스터, Kafka 토픽 또는 IAM 역할을 별도로 구성할 필요가 없었습니다. 전체 워크로드는 Snowflake 내에서 실행됐으며, 평가가 끝난 뒤에는 간편하게 환경을 해제할 수 있었습니다.

일반적으로 스트리밍 테스트를 시작하기 전에 필요했던 버킷, 클러스터, 인증 구성 및 각종 승인 절차가 더 이상 필수 조건은 아닙니다. 따라서 “이 방식이 우리 요구 사항을 빠르게 충족하는가?”라는 질문에 답할 수 있습니다.

대규모 미디어 또는 통신 플랫폼에서 사이트 신뢰성 엔지니어링(SRE)이나 데이터 엔지니어링을 담당하고 있고 Iceberg 스트리밍을 로드맵에 포함하고 있다면, 조달 절차가 아니라 테스트부터 시작해 보세요. 리포지토리를 복제하고 SPCS에 배포해 직접 실행 결과를 확인할 수 있습니다.

작성자 자세히 알아보기

Headshot of Dave Matthews

Dave Matthews

Senior Solution Engineer
이 게시물 공유하기

Subscribe to our blog newsletter

Get the best, coolest and latest delivered to your inbox each week