Snowpipe 문제 해결

Snowpipe 문제 해결

이 주제는 Snowpipe를 사용한 데이터 로드 문제를 체계적으로 해결하는 방법을 설명해요.

Snowpipe 문제를 해결하는 단계는 데이터 파일을 로드하는 데 사용된 워크플로에 따라 달라져요.

출처: Documentation

본문

클라우드 스토리지 이벤트 알림을 사용한 자동 데이터 로드

오류 알림

Snowpipe에 대한 오류 알림을 구성해요. Snowpipe가 로드 중에 오류를 만나면 이 기능은 구성된 클라우드 메시징 서비스로 알림을 푸시해 데이터 파일을 분석할 수 있게 해줘요. 자세한 내용은 Snowpipe 오류 알림을 참고해요.

일반 문제 해결 단계

다음 단계를 완료해 파일 자동 로드를 방해하는 대부분의 문제의 원인을 식별해요.

1단계: 파이프 상태 확인

파이프의 현재 상태를 검색해요. 결과는 JSON 형식으로 표시돼요. 자세한 내용은 SYSTEM$PIPE_STATUS를 참고해요.

다음 값을 확인해요.

  • lastReceivedMessageTimestamp — 메시지 큐에서 받은 마지막 이벤트 메시지의 타임스탬프. 이 메시지는 특정 파이프에 적용되지 않을 수 있어요. 예를 들어 메시지와 연결된 경로가 파이프 정의의 경로와 일치하지 않는 경우가 있어요. 또한 자동 수집 파이프는 생성된 데이터 객체로 트리거된 메시지만 소비해요. 타임스탬프가 예상보다 이르다면 서비스 구성(예: Amazon SQS 또는 Amazon SNS, Azure Event Grid) 또는 서비스 자체에 문제가 있음을 나타낼 가능성이 높아요. 필드가 비어 있으면 서비스 구성 설정을 확인해요. 필드에 타임스탬프가 있지만 예상보다 이르다면 서비스 구성에서 어떤 설정이 변경되었는지 확인해요.
  • lastForwardedMessageTimestamp — 일치하는 경로가 있고 파이프로 전달된 마지막 "객체 생성" 이벤트 메시지의 타임스탬프. 이벤트 메시지가 메시지 큐에서 수신되고 있지만 파이프로 전달되지 않는다면, 새 데이터 파일이 생성되는 blob 스토리지 경로와 Snowflake 스테이지 및 파이프 정의에 지정된 결합 경로 사이에 불일치가 있을 가능성이 높아요. 스테이지와 파이프 정의에 지정된 경로를 확인해요. 파이프 정의에 지정된 경로는 스테이지 정의의 모든 경로에 추가된다는 점에 주의해요.
2단계: 테이블의 COPY 기록 보기

이벤트 메시지가 수신되고 전달된다면 대상 테이블의 로드 활동 기록을 조회해요. 자세한 내용은 COPY_HISTORY를 참고해요.

STATUS 컬럼은 특정 파일 집합이 로드되었는지, 부분적으로 로드되었는지, 로드에 실패했는지 나타내요. FIRST_ERROR_MESSAGE 컬럼은 시도가 부분적으로 로드되거나 실패했을 때 그 이유를 제공해요.

파일 집합에 여러 문제가 있으면 FIRST_ERROR_MESSAGE 컬럼은 만난 첫 번째 오류만 나타낸다는 점에 주의해요. 파일의 모든 오류를 보려면 VALIDATION_MODE 복사 옵션을 RETURN_ALL_ERRORS로 설정한 COPY INTO <table> 문을 실행해요. VALIDATION_MODE 복사 옵션은 COPY 문이 로드될 데이터를 검증하고 지정된 검증 옵션에 따라 결과를 반환하도록 지시해요. 이 복사 옵션을 지정하면 데이터가 로드되지 않아요. 문에서 Snowpipe로 로드하려고 시도했던 파일 집합을 참조해요. 복사 옵션에 대한 자세한 내용은 COPY INTO <table>을 참고해요.

COPY_HISTORY 출력에 예상 파일 집합이 포함되지 않으면 더 이른 기간을 조회해요. 파일이 이전 파일의 중복이라면 로드 기록이 원본 파일 로드 시도 시점에 활동을 기록했을 수 있어요.

3단계: 데이터 파일 검증

로드 작업이 데이터 파일에서 오류를 만나면 COPY_HISTORY 테이블 함수는 각 파일에서 만난 첫 번째 오류를 설명해요. 데이터 파일을 검증하려면 VALIDATE_PIPE_LOAD 함수를 조회해요.

Microsoft Azure Data Lake Storage Gen2 스토리지에서 생성된 파일이 로드되지 않음

현재 일부 타사 클라이언트는 ADLS Gen 2 REST API에서 FlushWithClose를 호출하지 않아요. 이 단계는 Snowpipe에 파일을 로드하라고 알리는 이벤트를 트리거하는 데 필요해요. REST API를 수동으로 호출해 Snowpipe가 이러한 파일을 로드하도록 트리거해 보세요.

close 인자를 사용한 Flush 메서드에 대한 자세한 내용은 https://docs.microsoft.com/en-us/dotnet/api/azure.storage.files.datalake.datalakefileclient.flush을 참고해요. close 매개 변수의 로드에 대한 추가 REST API 참조 정보는 https://docs.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/update을 참고해요.

Amazon SNS 토픽 구독 삭제 후 Snowpipe가 파일 로드를 멈춤

사용자가 특정 Amazon Simple Notification Service(SNS) 토픽을 참조하는 파이프 객체를 처음 만들 때 Snowflake는 Snowflake 소유의 Amazon Simple Queue Service(SQS) 큐를 토픽에 구독해요. AWS 관리자가 SNS 토픽에 대한 SQS 구독을 삭제하면 해당 토픽을 참조하는 모든 파이프는 더 이상 Amazon S3에서 이벤트 메시지를 받지 않아요.

이 문제를 해결하려면:

  1. SNS 토픽 구독이 삭제된 시점부터 72시간을 기다려요. 72시간 후 Amazon SNS는 삭제된 구독을 지워요. 자세한 내용은 Amazon SNS 문서를 참고해요.
  2. 토픽을 참조하는 모든 파이프를 다시 만들어요(CREATE OR REPLACE PIPE 사용). 파이프 정의에서 같은 SNS 토픽을 참조해요. 지침은 3단계: 자동 수집이 활성화된 파이프 만들기를 참고해요.

SNS 토픽 구독 삭제 전에 작동했던 모든 파이프가 이제 S3에서 이벤트 메시지를 다시 받기 시작해야 해요.

72시간 지연을 피하려면 다른 이름으로 SNS 토픽을 만들 수 있어요. CREATE OR REPLACE PIPE 명령으로 토픽을 참조하는 모든 파이프를 다시 만들고 새 토픽 이름을 지정해요.

Google Cloud Storage에서 로드 지연 또는 파일 누락

Pub/Sub 메시지를 사용한 GCS(Google Cloud Storage)의 자동 데이터 로드가 구성되면 단일 스테이징 파일에 대한 이벤트 메시지만 읽힐 수 있어요. 또는 GCS에서 데이터 로드가 몇 분에서 하루 이상 지연될 수 있어요. 일반적으로 두 문제 모두 GCS 관리자가 Snowflake 서비스 계정에 Monitoring Viewer 역할을 부여하지 않았기 때문에 발생해요.

지침은 Google Cloud Storage용 Snowpipe 자동화의 "2단계: Snowflake에 Pub/Sub 구독 액세스 부여"를 참고해요.

Snowpipe REST 엔드포인트를 호출해 데이터 로드

오류 알림

Snowpipe 오류 알림 지원은 AWS(Amazon Web Services)에 호스팅된 Snowflake 계정에서 사용할 수 있어요. 데이터 로드 중 발생한 오류가 데이터 파일 분석을 가능하게 하는 알림을 트리거해요. 자세한 내용은 Snowpipe 오류 알림을 참고해요.

일반 문제 해결 단계

다음 단계를 완료해 파일 로드를 방해하는 대부분의 문제의 원인을 식별해요.

1단계: 인증 문제 확인

Snowpipe REST 엔드포인트는 JWT(JSON Web Token)와 함께 키 페어 인증을 사용해요.

Python/Java 수집 SDK가 JWT를 생성해요. REST API를 직접 호출할 때는 직접 생성해야 해요. 요청에 JWT 토큰이 제공되지 않으면 REST 엔드포인트는 오류 400을 반환해요. 잘못된 토큰이 제공되면 다음과 유사한 오류가 반환돼요.

snowflake.ingest.error.IngestResponseError: Http Error: 401, Vender Code: 390144, Message: JWT token is invalid.
2단계: 테이블의 COPY 기록 보기

Snowpipe를 사용한 시도된 데이터 로드를 포함해 테이블의 로드 활동 기록을 조회해요. 자세한 내용은 COPY_HISTORY를 참고해요. STATUS 컬럼은 특정 파일 집합이 로드되었는지, 부분적으로 로드되었는지, 로드에 실패했는지 나타내요. FIRST_ERROR_MESSAGE 컬럼은 시도가 부분적으로 로드되거나 실패했을 때 그 이유를 제공해요.

파일 집합에 여러 문제가 있으면 FIRST_ERROR_MESSAGE 컬럼은 만난 첫 번째 오류만 나타낸다는 점에 주의해요. 파일의 모든 오류를 보려면 VALIDATION_MODE 복사 옵션을 RETURN_ALL_ERRORS로 설정한 COPY INTO <table> 문을 실행해요. VALIDATION_MODE 복사 옵션은 COPY 문이 로드될 데이터를 검증하고 지정된 검증 옵션에 따라 결과를 반환하도록 지시해요. 이 복사 옵션을 지정하면 데이터가 로드되지 않아요. 문에서 Snowpipe로 로드하려고 시도했던 파일 집합을 참조해요. 복사 옵션에 대한 자세한 내용은 COPY INTO <table>을 참고해요.

3단계: 파이프 상태 확인

COPY_HISTORY 테이블 함수가 조사 중인 데이터 로드에 대해 결과가 0개를 반환하면 파이프의 현재 상태를 검색해요. 결과는 JSON 형식으로 표시돼요. 자세한 내용은 SYSTEM$PIPE_STATUS를 참고해요.

executionState 키는 파이프의 실행 상태를 식별해요. 예를 들어 PAUSED는 파이프가 현재 일시 중지되었음을 나타내요. 파이프 소유자는 ALTER PIPE로 파이프 실행을 재개할 수 있어요.

executionState 값이 파이프 시작 문제를 나타내면 자세한 정보를 위해 error 키를 확인해요.

4단계: 데이터 파일 검증

로드 작업이 데이터 파일에서 오류를 만나면 COPY_HISTORY 테이블 함수는 각 파일에서 만난 첫 번째 오류를 설명해요. 데이터 파일을 검증하려면 VALIDATE_PIPE_LOAD 함수를 조회해요.

기타 문제

파일 집합이 로드되지 않음

로드에 대한 COPY_HISTORY 레코드 누락

파이프의 COPY INTO <table> 문에 PATTERN 절이 포함되어 있는지 확인해요. 포함되어 있다면 PATTERN 값으로 지정된 정규식이 로드할 스테이징된 파일을 모두 필터링해 버리는지 확인해요.

PATTERN 값을 수정하려면 CREATE OR REPLACE PIPE 문법을 사용해 파이프를 다시 만들어야 해요.

자세한 내용은 CREATE PIPE를 참고해요.

COPY_HISTORY 레코드가 로드되지 않은 파일 부분집합을 나타냄

COPY_HISTORY 함수 출력이 파일 부분집합이 로드되지 않았음을 나타내면 파이프를 "새로 고침"해 볼 수 있어요.

이 상황은 다음 상황 중 어느 경우에든 발생할 수 있어요.

  • 외부 스테이지가 이전에 COPY INTO <table> 명령을 사용해 대량 데이터 로드에 사용됨.
  • REST API: 외부 이벤트 주도 기능이 REST API를 호출하는 데 사용되고, 이벤트가 구성되기 전에 외부 스테이지에 데이터 파일 백로그가 이미 존재함.
  • 자동 수집: 이벤트 알림이 구성되기 전에 외부 스테이지에 데이터 파일 백로그가 이미 존재함. / 이벤트 알림 실패로 파일 집합이 큐에 들어가지 못함.

구성된 파이프를 사용해 외부 스테이지의 데이터 파일을 로드하려면 ALTER PIPE … REFRESH 문을 실행해요.

대상 테이블의 중복 데이터

SHOW PIPES를 실행하거나 Account Usage의 PIPES 뷰 또는 정보 스키마의 PIPES 뷰를 조회해 계정의 모든 파이프 정의에서 COPY INTO <table> 문을 비교해요. 여러 파이프가 COPY INTO <table> 문에서 같은 클라우드 스토리지 위치를 참조한다면 디렉터리 경로가 겹치지 않는지 확인해요. 그렇지 않으면 여러 파이프가 같은 데이터 파일 집합을 대상 테이블에 로드할 수 있어요. 예를 들어 여러 파이프 정의가 <storage_location>/path1/과 <storage_location>/path1/path2/ 같은 서로 다른 세분화 수준으로 같은 스토리지 위치를 참조하면 이 상황이 발생할 수 있어요. 이 예제에서 파일이 <storage_location>/path1/path2/에 스테이징되면 두 파이프 모두 파일 복사본을 로드하게 돼요.

수정된 데이터를 다시 로드할 수 없음, 수정된 데이터가 의도치 않게 로드됨

Snowflake는 파일 로드 메타데이터를 사용해 같은 파일을 다시 로드하고 테이블에서 데이터를 중복하는 것을 방지해요. Snowpipe는 나중에 수정되었더라도(즉, 다른 eTag를 가졌더라도) 같은 이름의 파일 로드를 방지해요.

파일 로드 메타데이터는 테이블이 아닌 파이프 객체와 연결되므로 다음 결과가 발생해요.

  • 이미 로드된 파일과 같은 이름의 스테이징된 파일은 수정되었더라도(예: 새 행이 추가되거나 파일의 오류가 수정된 경우) 무시돼요.
  • 파이프의 COPY 작업 중 로드할 수 없었던 파일(예: 잘못된 파일 내용 또는 스테이지 액세스 실패 때문에)은 여전히 파이프의 메타데이터에 등록돼요. 등록된 파일 이름은 ALTER PIPE … REFRESH를 포함한 이후의 파이프 활동에 의해 무시돼요. COPY 문을 사용해 건너뛴 파일을 수동으로 로드할 수 있어요.
  • TRUNCATE TABLE 명령으로 테이블을 잘라도 Snowpipe 파일 로드 메타데이터는 삭제되지 않아요.

그러나 파이프는 로드 기록 메타데이터를 14일 동안만 유지 관리해요. 따라서:

  • 14일 내에 수정되어 다시 스테이징된 파일: Snowpipe는 다시 스테이징된 수정된 파일을 무시해요. 수정된 데이터 파일을 다시 로드하려면 현재 CREATE OR REPLACE PIPE 문법을 사용해 파이프 객체를 다시 만들어야 해요. 다음 예제는 Snowpipe REST API를 사용한 데이터 로드 준비의 1단계 예제를 기반으로 mypipe 파이프를 다시 만들어요.
    create or replace pipe mypipe as copy into mytable from @mystage;
    
  • 14일 후에 수정되어 다시 스테이징된 파일: Snowpipe가 데이터를 다시 로드해 대상 테이블에 중복 레코드가 발생할 수 있어요.

또한 활성 Snowpipe 로드와 같은 버킷/컨테이너, 경로, 대상 테이블을 참조하는 COPY INTO <table> 문을 실행하면 대상 테이블에 중복 레코드가 로드될 수 있어요. COPY 명령과 Snowpipe의 로드 기록은 Snowflake에 별도로 저장돼요. 이력 스테이징 데이터를 로드한 후 파이프 구성을 사용해 데이터를 수동으로 로드해야 한다면 ALTER PIPE … REFRESH 문을 실행해요. 자세한 내용은 이 주제의 파일 집합이 로드되지 않음을 참고해요.

CURRENT_TIMESTAMP로 삽입된 로드 시간이 COPY_HISTORY 뷰의 LOAD_TIME 값보다 이름

테이블 설계자가 레코드가 테이블에 로드될 때 현재 타임스탬프를 기본 값으로 삽입하는 타임스탬프 컬럼을 추가할 수 있어요. 의도는 각 레코드가 테이블에 로드된 시간을 캡처하는 것이지만, 타임스탬프는 COPY_HISTORY 함수(정보 스키마) 또는 COPY_HISTORY 뷰(Account Usage)가 반환하는 LOAD_TIME 컬럼 값보다 이르다. 이 시간 차이는 CURRENT_TIMESTAMP가 레코드가 테이블에 삽입될 때(즉, 로드 작업의 트랜잭션이 커밋될 때)가 아니라 로드 작업이 클라우드 서비스에서 컴파일될 때 평가되기 때문이에요.

참고 — Snowpipe의 *copy_statement*에서는 다음 함수를 사용하지 않는 것을 권장해요.

  • CURRENT_DATE
  • CURRENT_TIME
  • CURRENT_TIMESTAMP
  • GETDATE
  • LOCALTIME
  • LOCALTIMESTAMP
  • SYSDATE
  • SYSTIMESTAMP

이러한 함수를 사용해 삽입된 시간 값이 COPY_HISTORY 함수 또는 COPY_HISTORY 뷰가 반환하는 LOAD_TIME 값보다 몇 시간 이르게 될 수 있는 것은 알려진 문제예요.

대신 METADATA$START_SCAN_TIME과 함께 INCLUDE_METADATA 복사 옵션을 사용해 레코드 로드의 더 정확한 표현을 제공해요. 자세한 내용은 CREATE PIPE 예제를 참고해요.

오류: 스테이지 {1}과 연결된 통합 {0}을 찾을 수 없음

003139=SQL compilation error:\nIntegration ''{0}'' associated with the stage ''{1}'' cannot be found.

이 오류는 외부 스테이지와 스테이지에 연결된 스토리지 통합 사이의 연결이 끊어졌을 때 발생할 수 있어요. 이는 스토리지 통합 객체가 (CREATE OR REPLACE STORAGE INTEGRATION을 사용해) 다시 생성되었을 때 발생해요. 스테이지는 스토리지 통합의 이름이 아닌 숨겨진 ID를 사용해 스토리지 통합에 연결돼요. 내부적으로 CREATE OR REPLACE 문법은 객체를 삭제하고 다른 숨겨진 ID로 다시 만들어요.

하나 이상의 스테이지에 연결된 후 스토리지 통합을 다시 만들어야 한다면 ALTER STAGE stage_name SET STORAGE_INTEGRATION = storage_integration_name을 실행해 각 스테이지와 스토리지 통합 사이의 연결을 다시 설정해야 해요. 여기서:

  • stage_name은 스테이지의 이름.
  • storage_integration_name은 스토리지 통합의 이름.

정부 리전을 참조하는 Snowpipe 오류

계정이 상용 리전에 있는 동안 정부 리전의 버킷을 참조하는 Snowpipe에서 오류가 발생할 수 있어요. 클라우드 제공업체의 정부 리전은 다른 상용 리전으로 또는 다른 상용 리전에서 이벤트 알림을 보내는 것을 허용하지 않는다는 점에 주의해요. 자세한 내용은 AWS GovCloud(US)와 Azure Government를 참고해요.

대용량 파일이 로드되지 않음

Snowpipe 자동 수집은 데이터 로드를 트리거하기 위해 AWS S3 이벤트 알림에 의존해요. 멀티파트 업로드를 사용해 S3에 대용량 파일을 업로드하면 생성되는 이벤트 알림은 S3:ObjectCreated:CompleteMultipartUpload예요. S3 버킷의 이벤트 알림 구성에 S3:ObjectCreated:Put, S3:ObjectCreated:Post 또는 S3:ObjectCreated:Copy만 포함되어 있으면 Snowpipe는 이러한 대용량 파일을 자동으로 수집하지 않아요. 대용량 파일은 COPY_HISTORY 뷰나 SYSTEM$PIPE_STATUS 함수 결과에 표시되지 않아요.

이 문제를 피하려면 S3 버킷 이벤트 알림 구성에 S3:ObjectCreated:CompleteMultipartUpload가 포함되어 있는지 확인하거나, 단순하게는 All object create events로 설정해 모든 객체 생성 이벤트를 캡처해요.

다음 문제 해결 단계를 수행할 수 있어요.

  • 파일 크기 확인: 수집되지 않는 파일이 멀티파트 업로드의 일반적인 임계값(종종 약 16MiB이지만 구성할 수 있음)보다 큰지 확인해요.
  • S3 이벤트 알림 구성 확인:
    • AWS S3 콘솔로 이동해요.
    • Snowpipe 스테이지와 연결된 S3 버킷을 선택해요.
    • Properties로 이동하고 Event notifications로 이동해요.
    • 이벤트 알림 구성에 S3:ObjectCreated:CompleteMultipartUpload 이벤트가 포함되어 있는지 확인해요.
  • 권장 솔루션: All object create events 구성:
    • S3 이벤트 알림 구성에서 설정을 All object create events로 변경해요. 이렇게 하면 모든 객체 생성 이벤트 유형이 Snowflake로 전송되도록 보장돼요.
  • 이벤트 전달 확인:
    • 변경 후 S3 버킷에 대용량 파일을 업로드하고 AWS CloudWatch 로그(구성된 경우) 또는 Snowflake의 COPY_HISTORY를 모니터링해 이벤트가 전달되고 파일이 수집되고 있는지 확인해요.
    • SYSTEM$PIPE_STATUS 함수도 확인할 수 있어요.
  • S3 멀티파트 업로드 설정 검토:
    • 여전히 문제가 있으면 S3에 대용량 파일을 업로드하는 애플리케이션 또는 프로세스를 검토해요. 멀티파트 업로드를 사용하고 구성이 올바른지 확인해요.

더 알아보기