Elastic Channels 오류 처리
Elastic Channels 오류 처리
Elastic Channel append의 동기·비동기 오류 처리를 알려드릴게요. 승인(acknowledgement) 의미론, 중복 가능성, 재시도, 클라이언트 무효화 복구까지 이해할 수 있습니다.
출처: Snowflake 문서
본문
동기적 실패(Synchronous failures)
다음 실패는 append 호출 자체가 동기적으로 발생시킵니다.
- 검증 오류(필수 필드 누락, 미지원 타입)
- 직렬화 오류
- 닫힌 클라이언트 오류(클라이언트가 이미 닫힘)
- 즉각적인 배압(backpressure) — SDK의 로컬 버퍼가 가득 참
호출 지점에서 행·배치 데이터를 보관해 로그, 재시도, 또는 다른 곳으로 라우팅할 수 있게 하세요. 이 실패들은 비동기 오류 콜백을 호출하지 않아요.
로컬 배압 시 수입을 일시 중지하고 append가 거부된 이벤트를 보관하세요. 보류 중인 append가 빼내지게 두고 백오프와 함께 거부된 이벤트를 재시도하세요. 이후 append가 배압을 만났다고 해서 이전에 수락된 append를 재제출하지 마세요.
REST 요청의 경우 HTTP 400(Bad Request) 오류는 동기적이며, 요청이 수락되기 전에 거부되었음을 나타냅니다. 재시도 전에 요청 페이로드를 고치세요.
비동기 결과
콜백으로 추적되는 append
- 성공 콜백(
setSuccessHandler ): 내구성 승인 이후 호출됩니다. - 오류 콜백(
setErrorHandler ): 비동기 실패 후 호출됩니다.
Future 또는 Promise를 반환하는 append
Java:
CompletableFuture<Void> ack = channel.appendRowWithWait(row, "batch-1");
try {
ack.get();
// durable acknowledgement received
} catch (ExecutionException e) {
// asynchronous failure: log, buffer for retry, or raise
System.err.println("Append failed: " + e.getCause());
}
Python:
future = channel.append_row_with_wait(row, "batch-1")
try:
future.result()
# durable acknowledgement received
except Exception as e:
# asynchronous failure: log, buffer for retry, or raise
print("Append failed:", e)
Node.js:
try {
await channel.appendRowWithWait(row, "batch-1");
// durable acknowledgement received
} catch (err) {
// asynchronous failure: log, buffer for retry, or raise
console.error("Append failed:", err);
}
이 단일 append 예제들은 결과 처리 방식을 보여 주는 것으로, 매 행마다 기다리는 프로덕션 루프는 아닙니다. 처리량을 위해선 이벤트가 도착하면 append하고 제한된 Future·Promise 세트를 보관한 다음 모든 보류 중인 append가 내구성 있게 승인될 때까지 기다리세요. SDK가 내부적으로 일괄 처리합니다.
호출자 대기 타임아웃
호출자의 대기 마감시한은 SDK append의 결과와 분리되어 있어요. Java
원래 Future나 Promise와 미해결 이벤트를 보관하고, 필요하면 수입을 일시 중지하며, 원래 승인을 계속 관찰하세요. 호출자가 대기를 멈췄다고 해서 즉시 재제출하거나, 핸들을 취소하거나, 그 외 유효한 클라이언트를 다시 만들지 마세요. Java에서는 최종 승인을 보존해야 할 때 SDK의
모든 관련 이벤트가 성공한 후에만 애플리케이션 체크포인트를 전진시키세요. SDK가 종료적 오류나 무효화를 보고하면 아래 복구 지침을 따르세요. 프로세스가 손실되거나 미해결 append를 재생해야 한다면 그 결과를 모호한 것으로 취급하고 가능한 중복을 조정하기 위해 안정적인 이벤트 ID를 사용하세요.
내구성 승인 의미론
내구성 승인(durable acknowledgement)은 Snowflake가 append를 내구성 있게 버퍼링했음을 확인합니다. 이는 다음을 의미하지 않아요:
- 행이 대상 테이블에서 쿼리 가능하다는 것. 구체화(materialization)는 그 뒤에 일어나며 수 초가 걸릴 수 있어요.
- 행에 처리 오류가 없다는 것. 행은 승인 후 테이블 처리 중에도 여전히 실패할 수 있어요. 오류 로깅이 활성화되면 Snowflake는 진단과 복구를 위해 이 실패를 오류 테이블에 기록합니다.
At-least-once 전달과 중복
Elastic Channels는 at-least-once 전달을 제공합니다. 프로듀서가 모호한 결과(네트워크 타임아웃, 응답 없음, 5xx) 후 재시도하면 Snowflake가 원래 요청을 이미 수락했을 수 있고 대상 테이블에 중복 행이 있을 수 있어요.
콜백으로 추적되는 SDK append의 경우, 성공·오류 콜백 세부 정보가
REST 요청의 경우
데이터 모델에 안정적인 이벤트 식별자를 포함하고, 중복이 문제가 될 때 다운스트림에서 조정·중복 제거하세요. Append token은 애플리케이션 측 값이며 서버 측 중복을 방지하지 않아요.
재시도 지침
SDK는 클라이언트 프로세스가 실행되는 동안 append를 버퍼링하고 일시적 네트워크·서비스 실패를 내부적으로 재시도합니다. 승인이 아직 보류 중인 append에 대해 두 번째 재시도 루프를 시작하지 마세요. 이 재시도들은 크래시 복구를 제공하지 않아요. 버퍼링된 행과 복구 상태는 프로세스나 노드 실패를 가로질러 영속화되지 않습니다.
SDK가 종료적 append 실패를 보고하면 미해결 이벤트를 보관하고 재시도 전에 오류를 검사하세요. 아래 설명대로 무효화된 클라이언트를 다시 만드세요. 검증, 직렬화, 지속적 권한 부여 오류는 변경되지 않은 입력이나 구성을 재시도하는 대신 고치세요.
직접 REST 클라이언트는 요청 재시도를 소유합니다:
- HTTP 429(Too Many Requests)와 일시적 5xx 응답: 재시도 지연에 무작위 변동(jitter)이 있는 지수 백오프를 사용하세요.
- 네트워크 타임아웃이나 응답 없음: 요청이 이미 수락됐을 수 있어요. 재시도한다면 같은
requestId 를 재사용하고retryCount 를 증가시키며 가능한 중복을 조정하세요. - HTTP 400(Bad Request): 재시도 전에 요청 페이로드를 고치세요.
- HTTP 401 / 403: 실패가 지속되면 인증·권한을 고치세요. 변경되지 않은 자격 증명으로 무한정 재시도하지 마세요.
클라이언트 무효화
클라이언트가 무효화되면(Java의
클라이언트 또는 노드 실패 후 복구
이벤트를 마지막으로 알려진 결과로 분류하세요.
- 승인됨(Acknowledged): Snowflake가 append를 내구성 있게 버퍼링했습니다. 프로듀서가 재시작했다는 이유만으로 재생하지 마세요.
- 승인되지 않았고 보내지지 않았다고 알려짐: 소스나 내구성 있는 애플리케이션 버퍼에서 재생하세요.
- 결과가 알려지지 않은 승인 없음: append가 Snowflake에 도달했을 수 있어요. 필요하면 재생하되 행이 중복일 가능성이 있다고 취급하고 안정적인 이벤트 식별자로 조정하세요.
손실에 민감한 워크로드에서는 그 책임을 받아들이기 전에 미승인 데이터를 재생 가능한 소스나 프로듀서 측 내구성 저장소에 보관하세요. SDK의 프로세스 내 버퍼는 write-ahead 로그가 아니며 프로세스 유실 후 행을 복구할 수 없어요. 이는 모든 프로듀서에 Kafka나 외부 큐가 필요하다는 뜻은 아닙니다. 배포 선택과 로컬 스토리지 한도는 미승인 데이터 보호를 참고하세요.
행 수준 오류
대상 테이블에서 오류 로깅을 켜면 전용 오류 테이블에 행 수준 처리 실패를 포착할 수 있어요. 스키마 검증이나 타입 변환에 실패한 행은 오류 메시지와 함께 오류 테이블에 영속화됩니다. 자세한 내용은 고성능 아키텍처 Snowpipe Streaming의 오류 로깅을 참고하세요.
승인된 행이 대상 테이블에 안 보일 때 문제 해결
- 구체화가 완료되도록 몇 초 기다린 뒤 대상 테이블을 다시 조회하세요.
- 행 수준 처리 실패가 있는지 오류 테이블을 확인하세요.
- pipe가 활성이고 대상 테이블이 존재하는지 확인하세요.
- 채널 수준 오류 세부 정보는 SNOWPIPE_STREAMING_CHANNEL_HISTORY 뷰를 확인하세요.