스트림의 저장, 처리와 일관성 보장
스트림(Stream)은 Foundry에 들어온 행을 낮은 지연으로 후속 시스템에 제공하는 데이터 리소스입니다. 행은 영속성을 가진 핫 버퍼와 기반 파일시스템의 콜드 버퍼에 보관합니다. 데이터셋처럼 브랜치, 버전, 권한과 스키마를 관리하면서 최근 데이터에도 빠르게 접근할 수 있습니다.
스트림은 표 형식의 정형 데이터입니다. Avro 같은 개방형 형식을 사용하고 열에 대한 메타데이터를 스키마로 함께 저장합니다.
두 저장 계층
핫 버퍼
핫 버퍼(Hot buffer)는 새로 들어온 레코드를 저장하고, 스트림을 읽거나 변환하는 애플리케이션에 낮은 지연으로 제공합니다.
수집에는 최소 한 번 처리 보장이 적용됩니다. 플랫폼 안에서의 처리에는 선택적으로 정확히 한 번 처리 보장을 사용할 수 있습니다.
콜드 버퍼와 아카이빙
핫 버퍼의 데이터는 몇 분마다 콜드 버퍼(Cold buffer)로 옮겨집니다. 콜드 버퍼는 파일시스템 기반 저장 계층입니다. 이 이동 과정을 아카이빙이라고 하며, 옮겨진 데이터는 일반 Foundry 데이터셋으로 사용할 수 있습니다.
실시간으로 핫 버퍼를 읽지 못하는 애플리케이션도 아카이빙된 데이터를 처리할 수 있습니다. 스트림의 데이터셋 뷰는 플랫폼의 일반 데이터셋처럼 동작합니다.
두 계층을 함께 읽기
낮은 지연의 읽기를 지원하는 제품은 핫 버퍼의 최근 레코드와 콜드 버퍼의 이전 데이터를 함께 읽을 수 있습니다. 최근 데이터의 낮은 지연과 장기 저장의 낮은 비용을 결합하는 방식입니다.
행 단위 처리
일반 데이터셋과 달리 스트림 자체에는 파일 배치를 묶는 트랜잭션 경계가 없습니다. 각 행을 하나의 트랜잭션처럼 다루고 행별로 상태를 추적합니다.
이렇게 세밀하게 읽을 수 있으므로, 스트림 변환은 데이터를 정기적으로 모으거나 새 데이터가 있는지 계속 조회하는 방식에만 의존하지 않고 데이터 도착에 따라 처리할 수 있습니다.
스트림 유형 설정
스트림 유형은 핫 버퍼에 데이터를 쓰는 방식을 조정합니다. 메트릭에서 핫 버퍼 쓰기가 병목으로 나타날 때 변경을 검토합니다. 처리량을 높이는 설정이 언제나 지연을 줄이는 것은 아닙니다.
| 설정 | 효과 | 사용할 때 확인할 조건 |
|---|---|---|
| High Throughput | 많은 데이터를 초당 처리하도록 조정하며 추가 지연이 생길 수 있음 | 평균 배치 크기가 최대 배치 크기에 도달하거나 Kafka producer 배치 만료로 작업이 실패하는지 확인 |
| Compressed | 핫 버퍼로 보낼 메시지 배치를 압축하여 네트워크와 저장 공간 사용량을 줄임. 압축과 해제에 CPU가 추가로 필요 | 반복 문자열이 많고, 지연 누적이나 예상보다 낮은 처리량, 레코드 손실 등 대역폭 문제의 징후가 있는 경우 |
새 스트림은 생성 과정의 Define 페이지에서 설정합니다. 기존 스트리밍 데이터셋은 도구 모음의 Details → Stream Settings에서 유형과 압축을 변경할 수 있습니다.
파티션과 처리량
파티션(Partition)은 입력 스트림을 병렬로 처리하기 위한 내부 분할 단위입니다. 스트림을 만들 때 처리량 슬라이더로 파티션 수를 조정할 수 있습니다. 파티션 하나당 처리량 증가폭을 약 5mb/s로 잡는 경험값을 계획에 참고할 수 있지만, 고정 상한이나 실제 처리량을 보장하는 값은 아닙니다.
생산자와 소비자는 내부 파티션들을 직접 다루는 대신 하나의 스트림 인터페이스로 읽고 씁니다. 이 인터페이스와 처리 순서의 보장은 별개입니다. 스트리밍 동기화 설정의 처리량 선택에서는 도착 순서 보장과 연산 비용도 함께 확인합니다.
지원 필드 타입
스트림은 데이터셋과 같은 필드 타입을 지원합니다.
BOOLEAN, BYTE, SHORT, INTEGER, LONG, FLOAT, DOUBLE, DECIMAL,
STRING, MAP, ARRAY, STRUCT, BINARY, DATE, TIMESTAMP
복합 타입과 추가 매개변수는 데이터셋 스키마에서 설명합니다.
실행 그래프와 체크포인트
스트리밍 실행 작업은 내부적으로 작업 그래프(Job graph)로 표현됩니다. 데이터는 그래프의 방향을 따라 처리 단계를 통과하여 최종 출력에 도달합니다.
체크포인트 저장(Checkpointing)은 현재 연산 상태와 처리 위치를 함께 기록하여 장애 후 복구 지점을 만드는 방식입니다. 원천에서 주기적으로 생성한 체크포인트는 데이터와 함께 그래프를 통과합니다.
체크포인트가 모든 최종 출력에 도달하면, 원천이 그 체크포인트 전에 내보낸 행도 모두 출력에 도달한 상태입니다. 체크포인트에는 각 연산자의 상태와 마지막으로 처리한 데이터 위치를 저장합니다. 작업을 다시 시작할 때는 최신 체크포인트에서 복구하여 이미 처리한 전체 데이터를 처음부터 다시 읽는 일을 줄입니다.
스트리밍 작업의 Job Details에서 최근 체크포인트의 상태, 크기와 소요 시간을 실시간으로 확인할 수 있습니다.
일관성 보장
| 보장 | 동작 | 소비자가 고려할 사항 |
|---|---|---|
최소 한 번 처리 보장(AT_LEAST_ONCE) | 메시지를 최소 한 번 전달. 체크포인트 실패나 재시도에서는 같은 메시지를 여러 번 전달할 수 있음 | 중복 메시지를 처리하거나 허용하도록 설계해야 함 |
정확히 한 번 처리 보장(EXACTLY_ONCE) | 해당 처리 경계 안에서 메시지의 누락과 중복 없이 결과를 확정 | 중복 방지를 위한 조정과 추적으로 일반적으로 지연이 더 커짐 |
AT_LEAST_ONCE는 메시지를 잃지 않도록 하면서 레코드 확정 관리를 기다리지 않고 전달할 수 있어 보통 지연이 낮습니다. 대신 후속 애플리케이션이 중복을 처리해야 합니다.
EXACTLY_ONCE는 체크포인트를 사용하여 처리 결과의 일관성을 유지합니다. 해당 경계 안에서 중복 메시지 처리나 멱등 처리의 부담을 줄일 수 있습니다.
체크포인트와 가시성
EXACTLY_ONCE에서는 체크포인트가 완료된 뒤에야 레코드가 후속 단계에 보입니다. 기본 체크포인트 주기는 2초입니다. 레코드 자체는 계속 스트리밍 속도로 처리하지만, 외부에서 볼 수 있는 결과는 체크포인트로 확정된 뒤 공개됩니다.
적용 가능한 범위
| 경계 | 지원하는 보장 |
|---|---|
| 스트리밍 소스의 수집과 내보내기 | AT_LEAST_ONCE만 지원 |
| Foundry 스트리밍 파이프라인 | AT_LEAST_ONCE, EXACTLY_ONCE 모두 지원 |
파이프라인의 선택은 Pipeline Builder의 Build settings에서 구성합니다. 파이프라인에 EXACTLY_ONCE를 적용해도 수집과 외부 내보내기 경계까지 같은 보장으로 바뀌는 것은 아닙니다.