역방향 ETL을 사용하여 BigQuery에서 Spanner Graph로 데이터 로드

이 문서에서는 역방향 추출, 변환, 로드(ETL) 파이프라인을 사용하여 BigQuery에서 Spanner Graph로 그래프 데이터를 이동하고 지속적으로 동기화하는 방법을 설명합니다. 다음 주요 측면을 설명합니다.

역방향 ETL을 사용하여 BigQuery에서 Spanner로 데이터를 내보내려면 Spanner로 데이터 내보내기를 참조하세요.

BigQuery는 분석 처리 플랫폼으로 복잡한 데이터를 대규모로 조작하는 반면 Spanner는 높은 QPS 및 낮은 서빙 지연 시간이 필요한 사용 사례에 최적화되어 있습니다. Spanner Graph 및 BigQuery는 BigQuery 분석 파이프라인에서 그래프 데이터를 준비할 수 있도록 효과적으로 통합되며 이를 통해 Spanner에서 지연 시간이 짧은 그래프 순회를 제공할 수 있습니다.

시작하기 전에

  1. 그래프 데이터가 포함된 데이터베이스가 있는 Spanner 인스턴스를 만듭니다. 자세한 내용은 Spanner Graph 설정 및 쿼리를 참조하세요.

  2. BigQuery에서 Enterprise 또는 Enterprise Plus 등급 슬롯 예약을 만듭니다. Spanner Graph로 내보내기를 실행하면 BigQuery 컴퓨팅 비용을 줄일 수 있습니다. 이렇게 하려면 기준 슬롯 용량을 0으로 설정하고 자동 확장을 사용 설정합니다.

  3. 사용자에게 이 문서의 각 태스크를 수행하는 데 필요한 권한을 부여하는 Identity and Access Management(IAM) 역할을 부여합니다.

필요한 역할

BigQuery 그래프 데이터를 Spanner Graph로 내보내는 데 필요한 권한을 얻으려면 관리자에게 프로젝트에 대한 다음 IAM 역할을 부여해 달라고 요청하세요.

역할 부여에 대한 자세한 내용은 프로젝트, 폴더, 조직에 대한 액세스 관리를 참조하세요.

커스텀 역할이나 다른 사전 정의된 역할을 통해 필요한 권한을 얻을 수도 있습니다.

역방향 ETL 사용 사례

다음은 사용 사례 예시입니다. BigQuery에서 데이터를 분석하고 처리한 후 역방향 ETL을 사용하여 데이터를 Spanner Graph로 이동할 수 있습니다.

데이터 집계 및 요약 - BigQuery를 사용하여 세부 데이터에 대한 집계를 계산해 운영 사용 사례에 더 적합하게 만듭니다.

데이터 변환 및 보강 - BigQuery를 사용하여 다양한 데이터 소스에서 수신한 데이터를 정리하고 표준화합니다.

데이터 필터링 및 선택 - BigQuery를 사용하여 분석을 위해 대규모 데이터 세트를 필터링합니다. 예를 들어 실시간 애플리케이션에 필요하지 않은 데이터를 필터링할 수 있습니다.

특성 사전 처리 및 엔지니어링 - BigQuery에서 ML.TRANSFORM 함수를 사용하여 데이터를 변환하거나 ML.FEATURE_CROSS 함수를 사용하여 입력 특성의 특성 교차를 만듭니다. 그런 다음 역방향 ETL을 사용하여 결과 데이터를 Spanner Graph로 이동합니다.

역방향 ETL 파이프라인 이해

데이터는 역방향 ETL 파이프라인에서 다음 두 단계를 거쳐 BigQuery에서 Spanner Graph로 이동합니다.

  1. BigQuery는 파이프라인 작업에 할당된 슬롯을 사용하여 소스 데이터를 추출하고 변환합니다.

  2. BigQuery 역방향 ETL 파이프라인은 Spanner API를 사용하여 프로비저닝된 Spanner 인스턴스에 데이터를 로드합니다.

다음 다이어그램에서는 역방향 ETL 파이프라인의 단계를 보여줍니다.

역방향 ETL 파이프라인에서 데이터가 BigQuery에서 Spanner Graph로 이동할 때의 세 가지 주요 단계를 보여주는 다이어그램

그림 1. BigQuery 역방향 ETL 파이프라인 프로세스

그래프 데이터 변경사항 관리

역방향 ETL을 사용하여 다음 작업을 수행할 수 있습니다.

  • BigQuery에서 Spanner Graph로 그래프 데이터 세트 로드

  • BigQuery의 데이터 세트에서 지속적으로 업데이트되는 데이터와 Spanner Graph 데이터 동기화

SQL 쿼리를 사용하여 역방향 ETL 파이프라인을 구성해 소스 데이터와 적용할 변환을 지정합니다. 파이프라인은 삽입/업데이트(upsert) 작업을 사용하여 SELECT 문의 WHERE 절을 충족하는 모든 데이터를 Spanner에 로드합니다. 삽입/업데이트(upsert) 작업은 INSERT OR UPDATE 문과 동일합니다. 그래프 데이터를 저장하는 테이블에 새 행을 삽입하고 기존 행을 업데이트합니다. 파이프라인은 Spanner 테이블 기본 키의 새 행과 업데이트된 행을 기반으로 합니다.

로드 순서 종속 항목이 있는 테이블의 데이터 삽입 및 업데이트

Spanner Graph 스키마 설계 권장사항에서는 인터리브 처리된 테이블과 외래 키를 사용하는 것이 좋습니다. 인터리브 처리된 테이블이나 강제 외부 키를 사용하는 경우 특정 순서로 노드 및 에지 데이터를 로드해야 합니다. 이렇게 하면 참조 행을 만들기 전에 참조된 행이 존재합니다. 자세한 내용은 인터리브 처리된 테이블 만들기를 참조하세요.

다음 예시 그래프 입력 테이블 스키마는 인터리브 처리된 테이블과 외래 키 제약 조건을 사용하여 사용자와 계정 간의 관계를 모델링합니다.

CREATE TABLE Person (
  id    INT64 NOT NULL,
  name  STRING(MAX)
) PRIMARY KEY (id);

CREATE TABLE Account (
  id           INT64 NOT NULL,
  create_time  TIMESTAMP,
  is_blocked   BOOL,
  type        STRING(MAX)
) PRIMARY KEY (id);

CREATE TABLE PersonOwnAccount (
  id           INT64 NOT NULL,
  account_id   INT64 NOT NULL,
  create_time  TIMESTAMP,
  CONSTRAINT FK_Account FOREIGN KEY (account_id) REFERENCES Account (id)
) PRIMARY KEY (id, account_id),
  INTERLEAVE IN PARENT Person ON DELETE CASCADE;

CREATE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Person,
    Account
  )
  EDGE TABLES (
    PersonOwnAccount
      SOURCE KEY (id) REFERENCES Person
      DESTINATION KEY (account_id) REFERENCES Account
      LABEL Owns
  );

이 예시 스키마에서 PersonOwnAccountPerson의 인터리브 처리된 테이블입니다. PersonOwnAccount 테이블의 요소보다 먼저 Person 테이블의 요소를 로드합니다. 또한 PersonOwnAccount의 외래 키 제약 조건은 에지 관계 타겟인 Account에 일치하는 행이 있는지 확인합니다. 따라서 PersonOwnAccount 테이블보다 먼저 Account 테이블을 로드합니다. 다음 목록에는 이 스키마의 로드 순서 종속 항목이 요약되어 있습니다.

다음 단계를 수행하여 데이터를 로드합니다.

  1. PersonOwnAccount보다 먼저 Person을 로드합니다.
  2. PersonOwnAccount보다 먼저 Account를 로드합니다.

Spanner에서 예시 스키마의 참조 무결성 제약 조건을 적용합니다. 파이프라인에서 Person 테이블이나 Account 테이블에 일치하는 행이 없는 PersonOwnAccount 테이블에 행을 만들려고 하면 Spanner에서 오류를 반환합니다. 그러면 파이프라인이 실패합니다.

이 역방향 ETL 파이프라인 예시에서는 BigQuery의 EXPORTDATA 문을 사용하여 데이터 세트의 Person, Account, PersonOwnAccount 테이블에서 데이터를 내보내 로드 순서 종속성을 충족합니다.

BEGIN
EXPORT DATA OPTIONS (
    uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
    format='CLOUD_SPANNER',
    spanner_options="""{
      "table": "Person",
      "priority": "HIGH",
      "tag" : "graph_data_load_person"
    }"""
  ) AS
  SELECT
    id,
    name
  FROM
    DATASET_NAME.Person;

EXPORT DATA OPTIONS (
  uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
  format='CLOUD_SPANNER',
  spanner_options="""{
    "table": "Account",
    "priority": "HIGH",
    "tag" : "graph_data_load_account"
  }"""
) AS
SELECT
  id,
  create_time,
  is_blocked,
  type
FROM
  DATASET_NAME.Account;

EXPORT DATA OPTIONS (
  uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
  format='CLOUD_SPANNER',
  spanner_options="""{
    "table": "PersonOwnAccount",
    "priority": "HIGH",
    "tag" : "graph_data_load_person_own_account"
  }"""
) AS
SELECT
  id,
  account_id,
  create_time
FROM
  DATASET_NAME.PersonOwnAccount;
END;

데이터 동기화

BigQuery를 Spanner Graph와 동기화하려면 역방향 ETL 파이프라인을 사용합니다. 파이프라인에서 다음 중 하나를 수행하도록 구성할 수 있습니다.

  • BigQuery 소스의 삽입과 업데이트를 Spanner Graph 타겟 테이블에 적용합니다. 타겟 테이블에 스키마 요소를 추가하여 삭제를 논리적으로 전달하고 일정에 따라 타겟 테이블 행을 삭제할 수 있습니다.

  • 삽입 작업과 업데이트 작업을 적용하고 삭제 작업을 식별하는 시계열 함수를 사용합니다.

참조 무결성 제약 조건

Spanner와 달리 BigQuery는 기본 키 제약 조건과 외래 키 제약 조건을 적용하지 않습니다. BigQuery 데이터가 Spanner 테이블에 만든 제약 조건을 준수하지 않으면 해당 데이터를 로드할 때 역방향 ETL 파이프라인이 실패할 수 있습니다.

역방향 ETL은 자동으로 데이터를 커밋당 최대 변이 제한을 초과하지 않는 배치로 그룹화하고 임의의 순서로 Spanner 테이블에 배치를 원자적으로 적용합니다. 참조 무결성 검사를 실패한 데이터가 배치에 포함되어 있으면 Spanner는 해당 배치를 로드하지 않습니다. 이러한 실패 예시로는 상위 행이 없는 인터리브된 하위 행이나 참조된 열에 일치하는 값이 없는 적용된 외래 키 열이 있습니다. 배치가 검사를 통과하지 못하면 오류가 발생하면서 파이프라인이 실패하고 배치 로드를 중지합니다.

참조 무결성 제약 조건 오류 이해

다음은 발생할 수 있는 참조 무결성 제약 조건 오류를 보여주는 예시입니다.

외래 키 제약 조건 오류 해결
  • 오류: '외래 키 제약 조건 FK_Account가 테이블 PersonOwnAccount에서 위반되었습니다. Account(id)에서 참조된 값을 찾을 수 없습니다.'

  • 원인: FK_Account 외래 키에 필요한 Account 테이블의 일치하는 행이 누락되어 PersonOwnAccount 테이블에 행을 삽입하지 못했습니다.

상위 행 누락 오류 해결
  • 오류: 'PersonOwnAccount 테이블의 [15,1] 행에 대한 상위 행이 누락되었습니다.'

  • 원인: Person 테이블(id: 15)의 상위 행이 누락되어 PersonOwnAccount(id: 15account_id: 1)에 행을 삽입하지 못했습니다.

참조 무결성 오류 위험을 줄이려면 다음 옵션을 사용하는 것이 좋습니다. 옵션마다 장단점이 있습니다.

  • Spanner Graph에서 데이터를 로드할 수 있도록 제약 조건을 완화합니다.
  • 참조 무결성 제약 조건을 위반하는 행을 생략하는 로직을 파이프라인에 추가합니다.

참조 무결성 완화

데이터를 로드할 때 참조 무결성 오류를 방지하는 한 가지 방법은 Spanner에서 참조 무결성을 적용하지 않도록 제약 조건을 완화하는 것입니다.

  • 같은 물리적 행 인터리브 처리 특성을 사용하도록 INTERLEAVE IN 절이 있는 인터리브 처리된 테이블을 만들 수 있습니다. INTERLEAVE IN PARENT 대신 INTERLEAVE IN을 사용하면 Spanner에서 참조 무결성을 적용하지 않지만 관련 테이블이 같은 위치에 있으면 쿼리에 도움이 됩니다.

  • NOT ENFORCED 옵션을 사용하여 정보 외래 키를 만들 수 있습니다. NOT ENFORCED 옵션은 쿼리 최적화 이점을 제공합니다. 하지만 Spanner는 참조 무결성을 적용하지 않습니다.

예를 들어 참조 무결성 검사를 수행하지 않고 에지 입력 테이블을 만들려면 다음 DDL을 사용하면 됩니다.

CREATE TABLE PersonOwnAccount (
  id          INT64 NOT NULL,
  account_id  INT64 NOT NULL,
  create_time TIMESTAMP,
  CONSTRAINT FK_Account FOREIGN KEY (account_id) REFERENCES Account (id) NOT ENFORCED
) PRIMARY KEY (id, account_id),
INTERLEAVE IN Person;

역방향 ETL 파이프라인에서 참조 무결성 준수

파이프라인에서 참조 무결성 검사를 충족하는 행만 로드하게 하려면 PersonAccount 테이블에 일치하는 행이 있는 PersonOwnAccount 행만 포함합니다. 그런 다음 Spanner에서 PersonAccount 행을 참조하는 PersonOwnAccount 행보다 먼저 로드하도록 로드 순서를 유지합니다.

EXPORT DATA OPTIONS (
  uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
  format='CLOUD_SPANNER',
    spanner_options="""{
      "table": "PersonOwnAccount",
      "priority": "HIGH",
      "tag" : "graph_data_load_person_own_account"
    }"""
  ) AS
  SELECT
    poa.id,
    poa.account_id,
    poa.create_time
  FROM `PROJECT_ID.DATASET_NAME.PersonOwnAccount` poa
    JOIN `PROJECT_ID.DATASET_NAME.Person` p ON (poa.id = p.id)
    JOIN `PROJECT_ID.DATASET_NAME.Account` a ON (poa.account_id = a.id)
  WHERE poa.id = p.id
    AND poa.account_id = a.id;

그래프 요소 삭제

역방향 ETL 파이프라인은 삽입/업데이트(upsert) 작업을 사용합니다. 삽입/업데이트(upsert) 작업은 INSERT OR UPDATE 문과 동일하므로 파이프라인은 런타임 시 소스 데이터에 있는 행만 동기화할 수 있습니다. 즉, 파이프라인에서 삭제된 행을 제외합니다. BigQuery에서 데이터를 삭제하면 역방향 ETL 파이프라인이 Spanner Graph에서 같은 데이터를 직접 삭제할 수 없습니다.

다음 옵션 중 하나를 사용하여 BigQuery 소스 테이블에서 삭제를 처리할 수 있습니다.

소스에서 논리적 삭제 또는 소프트 삭제 수행

삭제할 행을 논리적으로 표시하려면 BigQuery에서 삭제됨 플래그를 사용합니다. 그런 다음 플래그를 전파할 수 있는 타겟 Spanner 테이블에 열을 만듭니다. 역방향 ETL에서 파이프라인 업데이트를 적용하면 Spanner에서 이 플래그가 있는 행을 삭제합니다. 파티션을 나눈 DML을 사용하여 이러한 행을 찾아 명시적으로 삭제할 수 있습니다. 또는 삭제 플래그 열에 종속된 날짜가 지정된 TTL(수명) 열을 구성하여 행을 암시적으로 삭제합니다. 논리적으로 삭제된 행이 제외되도록 Spanner 쿼리를 작성합니다. 이렇게 하면 Spanner가 예약된 삭제 전에 결과에서 이러한 행을 제외합니다. 역방향 ETL 파이프라인이 완료되면 Spanner는 행에 논리적 삭제를 반영합니다. 그런 다음 BigQuery에서 행을 삭제할 수 있습니다.

이 예시에서는 Spanner의 PersonOwnAccount 테이블에 is_deleted 열을 추가합니다. 그런 다음 is_deleted 값에 종속된 expired_ts_generated 열을 추가합니다. 생성된 열의 날짜가 DELETION POLICY 기준점보다 이전이므로 TTL 정책에서 영향을 받는 행 삭제를 예약합니다.

ALTER TABLE PersonOwnAccount
  ADD COLUMN is_deleted BOOL DEFAULT (FALSE);

ALTER TABLE PersonOwnAccount ADD COLUMN
  expired_ts_generated TIMESTAMP AS (IF(is_deleted,
    TIMESTAMP("1970-01-01 00:00:00+00"),
    TIMESTAMP("9999-01-01 00:00:00+00"))) STORED HIDDEN;

ALTER TABLE PersonOwnAccount
  ADD ROW DELETION POLICY (OLDER_THAN(expired_ts_generated, INTERVAL 0 DAY));

삽입, 업데이트, 논리적 삭제에 BigQuery 변경 내역 사용

변경 내역을 사용하여 BigQuery 테이블의 변경사항을 추적할 수 있습니다. GoogleSQL CHANGES 함수를 사용하여 특정 간격 동안에 변경된 행을 찾습니다. 그런 다음 삭제된 행 정보를 역방향 ETL 파이프라인과 함께 사용합니다. 파이프라인을 설정하여 Spanner 테이블에 삭제됨 플래그 또는 만료일과 같은 표시기를 설정할 수 있습니다. 이 표시기는 Spanner 테이블에서 삭제할 행을 표시합니다.

CHANGES 시계열 함수의 결과를 사용하여 역방향 ETL 파이프라인 로드에 포함할 소스 테이블의 행을 결정합니다.

소스 테이블에 행이 있는 경우 _CHANGE_TYPEINSERT 또는 UPDATE로 업데이트되는 행이 파이프라인에 포함됩니다. 소스 테이블의 현재 행은 최신 데이터를 제공합니다.

_CHANGE_TYPEDELETE로 사용하고 소스 테이블에 기존 행이 없는 행을 사용하여 Spanner 테이블에 삭제된 플래그 또는 행 만료일과 같은 표시기를 설정합니다.

내보내기 쿼리에서 BigQuery의 삽입 및 삭제 순서를 고려해야 합니다. 예를 들어 T1 시간에 삭제된 행과 이후 T2 시간에 삽입된 새 행을 가정해 보겠습니다. 두 행 모두 같은 Spanner 테이블 행에 매핑되는 경우 내보내기에서 이러한 이벤트의 효과를 원래 순서대로 유지해야 합니다.

설정된 경우 삭제 표시기는 Spanner 테이블에서 삭제할 행을 표시합니다.

예를 들어 각 행의 만료일이 저장되도록 Spanner 입력 테이블에 열을 추가할 수 있습니다. 그런 다음 이러한 만료일을 사용하는 삭제 정책을 만듭니다.

다음 예시에서는 테이블 행 만료일이 저장되도록 열을 추가하는 방법을 보여줍니다.

ALTER TABLE PersonOwnAccount ADD COLUMN expired_ts TIMESTAMP;

ALTER TABLE PersonOwnAccount
  ADD ROW DELETION POLICY (OLDER_THAN(expired_ts, INTERVAL 1 DAY));

BigQuery의 테이블에서 CHANGES 함수를 사용하려면 테이블의 enable_change_history 옵션TRUE로 설정합니다.

ALTER TABLE `PROJECT_ID.DATASET_NAME.PersonOwnAccount`
  SET OPTIONS (enable_change_history=TRUE);

다음 예시에서는 역방향 ETL을 사용하여 새로운 행이나 변경된 행을 업데이트하고 삭제로 표시된 행의 만료일을 설정하는 방법을 보여줍니다. PersonOwnAccount 테이블과의 LEFT JOIN을 통해 각 행의 현재 상태에 대한 쿼리 정보를 얻을 수 있습니다.

EXPORT DATA OPTIONS (
  uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
    format='CLOUD_SPANNER',
    spanner_options="""{
      "table": "PersonOwnAccount",
      "priority": "HIGH",
      "tag" : "graph_data_delete_via_reverse_etl"
    }"""
  ) AS
SELECT
  DISTINCT
   IF (changes._CHANGE_TYPE = 'DELETE', changes.id, poa.id) AS id,
   IF (changes._CHANGE_TYPE = 'DELETE', changes.account_id, poa.account_id) AS account_id,
   IF (changes._CHANGE_TYPE = 'DELETE', changes.create_time, poa.create_time) AS create_time,
   IF (changes._CHANGE_TYPE = 'DELETE', changes._CHANGE_TIMESTAMP, NULL) AS expired_ts
FROM
  CHANGES(TABLE `PROJECT_ID.DATASET_NAME.PersonOwnAccount`,
    TIMESTAMP_TRUNC(TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY), DAY),
    TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(), DAY)) changes
LEFT JOIN `PROJECT_ID.DATASET_NAME.PersonOwnAccount` poa
  ON (poa.id = changes.id
  AND poa.account_id = changes.account_id)
WHERE (changes._CHANGE_TYPE = 'DELETE'
   AND poa.id IS NULL)
   OR (changes._CHANGE_TYPE IN ( 'UPDATE', 'INSERT')
   AND poa.id IS NOT NULL );

예시 쿼리에서는 소스 테이블과 함께 LEFT JOIN을 사용하여 순서를 유지합니다. 이 조인을 사용하면 쿼리 변경 내역 간격 동안 삭제되었다가 다시 생성된 행에 대한 DELETE 변경 레코드가 무시됩니다. 파이프라인은 유효한 새 행을 유지합니다.

행을 삭제하면 파이프라인은 _CHANGE_TIMESTAMP 열의 DELETE 타임스탬프를 사용하여 해당 Spanner Graph 행의 expired_ts 열을 채웁니다. Spanner의 행 삭제 정책(TTL 정책)은 expired_ts 값이 하루 이상 지난 행을 삭제합니다.

시스템 신뢰성을 보장하려면 파이프라인 일정, 변경사항 되돌아보기 기간, Spanner TTL 정책을 조정합니다. 파이프라인이 매일 실행되도록 예약합니다. Spanner TTL 정책 기간은 이 실행 간격보다 길어야 합니다. 이렇게 하면 파이프라인이 Spanner TTL 정책에 의해 이미 삭제된 행에 대해 이전 DELETE 이벤트를 다시 처리하지 않습니다.

이 예시에서는 이전 UTC 날짜의 모든 BigQuery 테이블 변경사항을 캡처하는 일일 쿼리의 start_timestampend_timestamp 간격을 보여줍니다. 일괄 쿼리이고 CHANGES 함수에 제한이 있으므로 end_timestamp는 현재 시간보다 최소 10분 이상 이전이어야 합니다. 따라서 이 쿼리가 자정(UTC) 이후 최소 10분 이상 지난 후에 실행되도록 예약합니다. 자세한 내용은 CHANGES 문서를 참조하세요.

마지막으로 확인한 타임스탬프와 함께 TTL 열 사용

역방향 ETL 파이프라인은 Spanner 테이블의 행마다 last_seen_ts 열을 현재 타임스탬프로 설정합니다. BigQuery 행을 삭제해도 Spanner는 해당 행을 업데이트하지 않으며 last_seen_ts 열도 변경되지 않습니다. 그런 다음 Spanner는 정의된 기준점에 따라 TTL 정책이나 파티션을 나눈 DML을 사용하여 오래된 last_seen_ts가 있는 행을 삭제합니다. 예약된 삭제 전에 Spanner 쿼리에서 이 기준점보다 오래된 last_seen_ts가 있는 행을 필터링할 수 있습니다. 이 방법은 그래프 데이터가 정기적으로 업데이트되고 업데이트가 누락되면 삭제할 비활성 데이터가 표시되는 경우에 효과적입니다.

전체 새로고침 수행

BigQuery에서 로드하기 전에 Spanner 테이블을 삭제하여 소스 테이블의 삭제를 반영할 수 있습니다. 이렇게 하면 다음 파이프라인 실행 중에 소스 BigQuery 테이블에서 삭제된 행이 Spanner에 로드되지 않습니다. 이 옵션이 구현하기 가장 쉬운 옵션일 수 있습니다. 하지만 그래프 데이터를 완전히 새로고침하는 데 필요한 시간을 고려하세요.

예약된 일괄 역방향 ETL 파이프라인 유지보수

역방향 ETL 파이프라인을 처음 실행하여 BigQuery에서 Spanner Graph로 데이터를 대량 로드한 후에도 실제 데이터는 계속 변경됩니다. 데이터 세트가 변경되고 파이프라인은 시간이 경과함에 따라 그래프 요소를 추가하거나 삭제합니다. 파이프라인에서 새 노드를 탐색하고 새 에지 관계를 추가하거나 AI 추론에서 이를 생성합니다.

Spanner Graph 데이터베이스가 최신 상태로 유지되도록 다음 옵션 중 하나를 사용하여 BigQuery 파이프라인 조정을 예약하고 순서를 지정합니다.

BigQuery 파이프라인을 사용하면 BigQuery에서 복잡한 SQL 데이터 변환 워크플로를 개발, 테스트, 버전 관리, 배포할 수 있습니다. 파이프라인의 쿼리 간 관계를 정의하여 순서 종속 항목을 기본적으로 처리합니다. Dataform은 종속 항목 트리를 빌드하고 올바른 순서로 쿼리를 실행합니다. 이렇게 하면 다운스트림 태스크가 시작되기 전에 업스트림 종속 항목이 완료됩니다.

Cloud Scheduler에서 호출하는 Workflows는 BigQuery 쿼리를 포함한Google Cloud 서비스 시퀀스를 조정하는 유용하고 유연한 솔루션을 제공합니다. 각각 BigQuery 작업을 실행하는 일련의 단계로 워크플로를 정의합니다. Cloud Scheduler를 사용하여 정의된 일정에 따라 이러한 워크플로를 호출할 수 있습니다. 워크플로 정의를 사용하여 종속 항목을 관리하여 실행 순서를 지정하고 조건부 로직을 구현하고 오류를 처리하며 한 쿼리에서 다른 쿼리로 출력을 전달합니다.

BigQuery의 예약된 쿼리(BigQuery 전송 작업이라고도 함)를 사용하면 SQL 문을 반복해서 실행할 수 있습니다. 예약된 쿼리는 강력한 오류 처리나 동적 종속 항목 관리를 제공하지 않습니다.

BigQuery 연속 쿼리를 사용한 역방향 ETL

BigQuery 연속 쿼리 기능을 사용하면 거의 실시간으로 BigQuery 작업을 실행할 수 있습니다. EXPORT DATA를 연속 쿼리와 결합하면 예약된 일괄 작업을 피하는 역방향 ETL 파이프라인을 실행하는 대체 방법이 제공됩니다.

연속 쿼리는 소스 BigQuery 테이블에서 새 행을 모니터링하는 장기 실행 쿼리입니다. BigQuery는 테이블에 추가된 새 행을 감지하면 쿼리 결과를 EXPORT DATA 작업으로 스트리밍합니다.

이 방식에는 다음과 같은 장점이 있습니다.

  • 거의 실시간으로 데이터 동기화: BigQuery의 새 행이 최소화된 지연 시간으로 Spanner에 반영됩니다.

  • 일괄 처리 오버헤드 감소: 연속 쿼리를 사용하면 주기적인 일괄 작업이 필요하지 않으므로 컴퓨팅 오버헤드가 줄어듭니다.

  • 이벤트 기반 업데이트: BigQuery의 실제 변경사항에 따라 Spanner 데이터가 업데이트됩니다.

연속 쿼리 파이프라인을 사용하려면 CONTINUOUSjob_type이 있는 슬롯 예약 할당이 필요합니다. 프로젝트 또는 폴더 수준이나 조직 수준에서 이를 할당합니다.

BigQuery에서 Spanner로의 역방향 ETL을 사용하여 연속 쿼리 만들기

APPENDS 함수의 start_timestamp 파라미터를 구성하여 일괄 로드가 중단된 지점에서 데이터 처리를 시작합니다. 이 함수는 특정 기간에 생성된 모든 행을 캡처합니다. 다음 예시에서 파이프라인은 시작 지점을 임의로 CURRENT_TIME 10분 전으로 설정합니다. 이 타임스탬프는 BigQuery 시간 이동 기간 내에 있어야 합니다.

연속 쿼리 파이프라인을 시작하는 방법에는 다음과 같은 여러 가지 방법이 있습니다.

  1. BigQuery Studio에서 더보기를 선택하고 쿼리 모드 선택에서 연속 쿼리를 선택합니다.

  2. bq CLI를 사용하고 --continuous=true 옵션을 제공합니다.

EXPORT DATA OPTIONS ( uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
  format="CLOUD_SPANNER",
  spanner_options="""{
      "table": "PersonOwnAccount",
      "priority": "HIGH",
      "tag": "reverse-etl-continuous",
      "change_timestamp_column": "create_time"
   }"""
)
AS SELECT id, account_id, _CHANGE_TIMESTAMP as create_time
  FROM
APPENDS(TABLE `PROJECT_ID.DATASET_NAME.PersonOwnAccount`,
  CURRENT_TIMESTAMP() - INTERVAL 10 MINUTE )

로드 순서가 보장되지 않음

Spanner Graph 데이터는 입력 테이블 여러 개로 구성됩니다. 테이블에 참조 무결성 제약 조건이 있으면 엄격한 로드 순서를 준수해야 합니다. 하지만 동시 연속 쿼리는 Spanner에서 행을 추가하는 순서를 제어할 수 없습니다. 따라서 연속 쿼리를 사용하여 Spanner Graph 데이터 로드는 참조 무결성 제약 조건이 완화된 그래프 스키마에만 해당됩니다.

기존 파이프라인과 통합

연속 쿼리는 기존의 예약된 일괄 작업을 보완합니다. 예를 들어 거의 실시간 업데이트에는 연속 쿼리를, 전체 데이터 동기화나 조정에는 예약된 작업을 사용합니다.

BigQuery 연속 쿼리를 사용하여 BigQuery와 Spanner Graph 간에 데이터를 동기화할 수 있는 최신 반응형 역방향 ETL 파이프라인을 빌드합니다.

연속 쿼리 고려사항

  • 비용: 연속 쿼리를 실행하면 지속적인 쿼리 실행과 데이터 스트리밍에 대한 비용이 발생합니다.

  • 오류 처리: 중복 기본 키 또는 참조 무결성 위반과 같은 데이터베이스 오류가 발생하면 연속 쿼리 파이프라인이 취소됩니다. 파이프라인이 실패하면 쿼리를 다시 시작하기 전에 소스 BigQuery 테이블의 데이터를 수동으로 수정해야 합니다.

  • 삭제 및 업데이트가 처리되지 않음: APPENDS 함수는 삽입만 캡처합니다. 삭제 또는 업데이트를 캡처하지 않습니다.

역방향 ETL 권장사항 따르기

최상의 결과를 얻으려면 다음을 수행합니다.

  • 에지 데이터를 로드할 때 참조 무결성 오류가 방지되는 전략을 선택합니다.

  • 댕글링 에지가 방지되도록 전체 데이터 파이프라인을 설계합니다. 댕글링 에지는 Spanner Graph 쿼리 효율성과 그래프 구조 무결성을 저해할 수 있습니다. 자세한 내용은 댕글리 에지 방지를 참조하세요.

  • Spanner 내보내기 최적화 권장사항을 따릅니다.

  • 많은 양의 데이터를 로드하는 경우 기본 6시간 BigQuery 쿼리 실행 시간 할당량에 도달하지 않도록 파이프라인을 작은 파이프라인 여러 개로 나누는 것이 좋습니다. 자세한 내용은 BigQuery 쿼리 작업 한도를 참조하세요.

  • 대량의 데이터를 로드하는 경우 초기 대량 데이터 로드가 완료된 후 색인과 외래 키 제약 조건을 추가합니다. 외래 키 제약 조건에는 검증을 위한 추가 읽기가 필요하고 색인에는 추가 쓰기가 필요하므로 이 방법을 사용하면 데이터 로드 성능이 향상됩니다. 이러한 작업은 트랜잭션 참여자 수를 늘리므로 데이터 로드 프로세스가 느려질 수 있습니다.

  • Spanner에서 자동 확장을 사용 설정하여 인스턴스로의 데이터 로드 시간을 단축합니다. 그런 다음 BigQuery EXPORT DATA 명령의 spanner_options 섹션에서 Spanner priority 파라미터를 HIGH로 구성합니다. 자세한 내용은 Spanner 자동 확장 개요, spanner_options 옵션으로 내보내기 구성, RequestOptions.priority를 참조하세요.

  • 대량의 데이터를 로드하는 경우 분할 지점을 만들어 데이터베이스를 사전 분할합니다. 이렇게 하면 처리량이 증가하도록 Spanner가 준비됩니다.

  • 파이프라인 정의에서 데이터 로드에 대한 Spanner 요청 우선순위를 구성합니다.

다음 단계