AlloyDB에서 Iceberg 데이터 액세스

PostgreSQL용 AlloyDB에서 Iceberg에 직접 액세스하면 AlloyDB 인스턴스에서 Cloud Storage의 Apache Iceberg 테이블 형식으로 저장된 데이터를 쿼리할 수 있습니다. Cloud Storage 버킷 URI 또는 Lakehouse 런타임 카탈로그를 사용하여 Iceberg 데이터 세트에 액세스할 수 있습니다. 분석 워크로드의 속도를 높이기 위해 AlloyDB는 스캔, 조인, 집계를 최적화하는 기본 제공 열 기반 엔진을 제공합니다. 열 기반 엔진과 통합하면 Iceberg에 직접 액세스하여 복잡한 추출, 변환, 로드(ETL) 데이터 파이프라인을 빌드, 관리, 유지보수하지 않고도 데이터 레이크하우스에서 고성능 분석 쿼리를 실행할 수 있습니다.

표준 SQL 명령어를 사용하여 Iceberg 테이블을 쿼리하고, Iceberg 데이터 세트를 AlloyDB의 운영 테이블과 조인하고, Iceberg 테이블을 인메모리 열 기반 엔진에 채워 쿼리 성능을 가속화할 수 있습니다.

이점

직접 Iceberg 액세스는 다음과 같은 이점을 제공합니다.

  • Zero-ETL 레이크하우스 액세스: 데이터를 별도의 분석 시스템으로 복사하거나 이동하지 않고 외부 Iceberg 데이터 세트를 즉시 쿼리합니다.
  • 통합 트랜잭션 및 분석 쿼리: AlloyDB 힙 테이블에 저장된 실시간 운영 데이터를 Cloud Storage의 Iceberg 테이블에 저장된 대규모 이전 데이터와 조인합니다.
  • 유연한 카탈로그 통합: Cloud Storage 버킷 경로 또는 Lakehouse 런타임 카탈로그를 통해 Iceberg 테이블 메타데이터에 액세스합니다.
  • 열 기반 쿼리 가속화: 1초 미만의 분석 처리를 위해 Iceberg 테이블을 AlloyDB 열 기반 엔진 메모리에 캐시하고 채웁니다.
  • 표준 SQL 인터페이스: 익숙한 PostgreSQL 문법을 사용하여 Iceberg 테이블을 쿼리하고 분석합니다.

직접 Iceberg 액세스 작동 방식

Iceberg 직접 액세스는 PostgreSQL 테이블 액세스 메서드(TAM) 인터페이스(USING iceberg)를 사용하고 AlloyDB 열 기반 엔진 플래너 및 실행 프레임워크와 통합됩니다.

Iceberg 테이블을 쿼리하면 AlloyDB는 다음 모드 중 하나로 작동합니다.

  • 직접 스캔(스트리밍 읽기): AlloyDB는 Cloud Storage에서 최신 메타데이터 및 데이터 파일을 직접 읽습니다. 열 기반 엔진은 스트리밍 방식으로 데이터를 처리합니다.
  • 열 기반 엔진 가속화(메모리 캐시된 읽기): google_columnar_engine_add() 함수를 사용하여 Iceberg 테이블을 AlloyDB 열 기반 엔진에 채우면 테이블이 메모리의 열 기반 스토어에 로드됩니다. 후속 쿼리는 열 기반 엔진 메모리에서 읽어 쿼리 처리량을 극대화하고 지연 시간을 최소화합니다.

스냅샷 서빙 및 캐시 새로고침

AlloyDB가 쿼리하는 Iceberg 테이블 스냅샷은 읽기 모드에 따라 달라집니다.

  • 직접 스캔: AlloyDB는 최신 Iceberg 스냅샷에서 쿼리를 실행합니다. 쿼리가 시작되면 AlloyDB는 REPEATABLE READ 또는 SERIALIZABLE 트랜잭션 내에서도 사용 가능한 최신 Iceberg 테이블 스냅샷을 확인하고 해당 스냅샷에서 데이터를 읽습니다. AlloyDB는 트랜잭션 간 스냅샷 고정 및 시점 쿼리를 지원하지 않습니다.

    예를 들어 직접 스캔을 사용하여 테이블을 쿼리하면 트랜잭션의 각 문이 사용 가능한 최신 스냅샷에서 읽습니다.

    BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    SELECT * FROM customer_orders;
    -- If an external process commits a new Iceberg snapshot:
    SELECT * FROM customer_orders; -- Returns results from the new snapshot.
    COMMIT;
    
  • 열 기반 엔진 가속화: AlloyDB는 열 기반 엔진에 채워진 스냅샷에서 쿼리를 실행합니다. AlloyDB가 채우기 후 Cloud Storage의 기본 Iceberg 테이블에 새 데이터를 쓰는 경우 쿼리에서 오래된 데이터를 반환할 수 있습니다. 기본 테이블에서 DML 작업 후 최신 데이터를 가져오려면 google_columnar_engine_refresh() 함수를 사용하여 캐시를 새로고침합니다.

지원되는 데이터 유형

AlloyDB에서 Iceberg 테이블을 정의할 때 DDL 문의 열 이름과 데이터 유형은 기본 Iceberg 스키마의 유형과 일치해야 합니다.

직접 Iceberg 액세스는 다음 Apache Iceberg 데이터 유형과 이에 상응하는 AlloyDB 유형을 지원합니다.

Apache Iceberg 데이터 유형 AlloyDB 데이터 유형 설명
boolean BOOLEAN 바이트 패킹 형식으로 벡터화된 변환
int INT/INTEGER 부호 있는 32비트 정수
long BIGINT 부호 있는 64비트 정수
float REAL/FLOAT4 32비트 단정밀도 부동 소수점
double DOUBLE PRECISION/FLOAT8 64비트 배정밀도 부동 소수점
decimal(P, S) NUMERIC(P, S)/DECIMAL(P, S) 정밀도가 P이고 비율이 S인 고정 소수점 숫자 값
string TEXT/VARCHAR UTF-8 문자열 값
date DATE 캘린더 날짜(연, 월, 일)
timestamp TIMESTAMP 시간대 없는 타임스탬프
timestamptz TIMESTAMPTZ 시간대 포함 타임스탬프

제한사항

직접 Iceberg 액세스에는 다음과 같은 제한사항이 있습니다.

  • PostgreSQL 버전 가용성: AlloyDB는 PostgreSQL 18 이상에서 직접 Iceberg 액세스를 지원합니다.
  • 사용자 권한: alloydbsuperuser 역할이 있는 데이터베이스 사용자만 Iceberg 테이블을 만들 수 있습니다. 테이블을 만든 후 다른 사용자에게 SELECT 권한을 부여하여 Iceberg 테이블을 쿼리할 수 있습니다.
  • 읽기 전용 작업: AlloyDB는 Iceberg 테이블에서 SELECT 쿼리(DQL)만 지원합니다. 쓰기 작업(INSERT, UPDATE, DELETE, TRUNCATE)은 지원하지 않습니다.
  • Apache Iceberg 사양 버전: AlloyDB는 Iceberg v2 삭제 파일(위치 및 동등 삭제) 또는 Iceberg v3 삭제 벡터를 지원하지 않습니다.
  • 파일 형식 지원: 직접 Iceberg 액세스는 Parquet 데이터 파일과 JSON 및 Avro 메타데이터 파일을 지원합니다. ORC 데이터 파일은 지원되지 않습니다.
  • 스냅샷 버전 관리: 직접 스캔 쿼리는 최신 Iceberg 테이블 스냅샷에서 실행되고 열 가속 쿼리는 채워진 스냅샷에서 실행됩니다. AlloyDB는 시점 쿼리를 지원하지 않습니다.
  • 스키마 변경: AlloyDB는 Iceberg 테이블에서 ALTER TABLE 작업을 지원하지 않습니다. 기본 Iceberg 테이블은 스키마 마이그레이션을 거치지 않아야 합니다.
  • 메타데이터 카탈로그 지원: 직접 Iceberg 액세스는 직접 Cloud Storage 버킷 경로(gs://) 및 Lakehouse 런타임 카탈로그 경로(bl://)를 지원합니다. Lakehouse 런타임 카탈로그의 경우 AlloyDB는 최종 사용자 인증 정보 모드만 지원합니다. 사용자 인증 정보 판매 모드 또는 기타 REST 카탈로그는 지원하지 않습니다.
  • 요청자 지불 버킷: AlloyDB는 요청자 지불을 사용하는 Cloud Storage 버킷을 지원하지 않습니다.
  • 전체 채우기 제약조건: AlloyDB는 Iceberg 테이블의 부분 열 채우기를 지원하지 않습니다. 테이블은 열 기반 엔진 메모리 또는 SSD 공간에 맞아야 합니다.
  • 채우기 힙 메모리: 대규모 Parquet 행 그룹이 포함된 Iceberg 테이블을 채우면 특히 vCPU가 적은 인스턴스에서 작업자당 채우기 힙 메모리 한도를 초과할 수 있습니다. 이 문제를 해결하려면 열 기반 엔진 채우기 힙이 가득 참을 참조하세요.

시작하기 전에

Iceberg 테이블을 만들고 쿼리하기 전에 다음을 완료해야 합니다.

  1. Google Cloud에서 PostgreSQL 18 이상을 실행하는 AlloyDB 클러스터를 만듭니다. 자세한 내용은 클러스터 만들기를 참조하세요.
  2. Cloud Storage에서 Apache Iceberg 테이블을 호스팅하거나 Lakehouse 런타임 카탈로그에 등록합니다.
    • Cloud Storage 경로의 경우 버킷 디렉터리 구조는 메타데이터 JSON 파일 및 version-hint.text를 포함하여 data/ 및 metadata/ 하위 디렉터리가 포함된 표준 Apache Iceberg 레이아웃을 따라야 합니다. 자세한 내용은 버킷 만들기를 참조하세요.
    • Lakehouse 런타임 카탈로그의 경우 최종 사용자 인증 정보 모드에서 Iceberg 카탈로그를 만들고 등록합니다. 자세한 내용은 Apache Iceberg REST 카탈로그 엔드포인트 설정을 참조하세요.
  3. alloydbsuperuser 역할이 있는 사용자의 데이터베이스 사용자 인증 정보를 설정합니다. 자세한 내용은 alloydbsuperuser 그룹 역할을 참고하세요.

필요한 역할

AlloyDB가 Iceberg 데이터 및 메타데이터를 읽을 수 있도록 하려면 AlloyDB 클러스터 서비스 계정에 필요한 IAM 역할을 부여해야 합니다.

  • Cloud Storage 액세스: Iceberg 데이터 및 메타데이터가 포함된 Cloud Storage 버킷에 스토리지 객체 뷰어(roles/storage.objectViewer) 역할을 부여합니다.
  • BigLake 액세스(레이크하우스 런타임 카탈로그를 사용하는 경우): BigLake 카탈로그를 호스팅하는 프로젝트에 BigLake 뷰어(roles/biglake.viewer) 역할을 부여합니다.

클러스터 서비스 계정을 찾으려면 gcloud beta alloydb clusters describe 명령어를 실행합니다.

gcloud beta alloydb clusters describe CLUSTER_ID --region=REGION_ID

다음을 바꿉니다.

  • CLUSTER_ID: AlloyDB 클러스터 ID
  • REGION_ID: AlloyDB 클러스터의 위치입니다. 예를 들면 us-east1입니다. 리전의 전체 목록은 AlloyDB 위치를 참조하세요.

출력에는 이 클러스터의 서비스 계정인 serviceAccountEmail 필드가 포함됩니다. Google Cloud 콘솔의 클러스터 개요 페이지에서 서비스 계정을 찾을 수 있습니다.

gcloud CLI를 사용하여 스토리지 객체 뷰어 역할을 부여하려면 다음을 실행합니다.

gcloud storage buckets add-iam-policy-binding \
    gs://BUCKET_NAME \
    --member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \
    --role="roles/storage.objectViewer"

Lakehouse 런타임 카탈로그를 사용하는 경우 BigLake 뷰어 역할을 부여합니다.

gcloud projects add-iam-policy-binding LAKEHOUSE_PROJECT_ID \
    --member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \
    --role="roles/biglake.viewer"

다음을 바꿉니다.

  • BUCKET_NAME: Cloud Storage 버킷 이름.
  • LAKEHOUSE_PROJECT_ID: Lakehouse 런타임 카탈로그가 호스팅되는 Google Cloud 프로젝트 ID입니다.
  • SERVICE_ACCOUNT_EMAIL: serviceAccountEmail 필드에서 찾은 클러스터 서비스 계정 이메일입니다.

데이터베이스 플래그 구성

열 기반 엔진과 직접 Iceberg 액세스를 사용 설정하려면 AlloyDB 인스턴스에서 데이터베이스 플래그를 구성하면 됩니다. 인스턴스에서 다음 데이터베이스 플래그를 설정합니다.

데이터베이스 플래그 값 설명
google_columnar_engine.enabled on AlloyDB 열 기반 엔진을 사용 설정합니다.
google_columnar_engine.enable_iceberg_reads on 직접 Iceberg 액세스를 사용 설정합니다. 인스턴스를 다시 시작해야 합니다.
google_columnar_engine.memory_size_in_mb SIZE_IN_MB (선택사항) 열 기반 엔진에 메모리를 할당합니다. 메모리에 Iceberg 테이블을 채우려는 경우 권장됩니다.

gcloud CLI를 사용하여 이러한 플래그를 구성하려면 gcloud alloydb instances update 명령어를 실행합니다.

gcloud alloydb instances update INSTANCE_ID \
    --cluster=CLUSTER_ID \
    --region=REGION_ID \
    --database-flags=google_columnar_engine.enabled=on,google_columnar_engine.enable_iceberg_reads=on

다음을 바꿉니다.

  • INSTANCE_ID: AlloyDB 인스턴스의 ID입니다.
  • CLUSTER_ID: AlloyDB 클러스터의 ID입니다.
  • REGION_ID: AlloyDB 클러스터의 지역 ID입니다.

AlloyDB에서 Iceberg 테이블 만들기

AlloyDB에서 Apache Iceberg 데이터 세트를 노출하려면 alloydbsuperuser 권한이 있는 사용자로 연결합니다. 그런 다음 USING iceberg 테이블 액세스 메서드를 사용하여 테이블을 만듭니다.

CREATE TABLE TABLE_NAME (
    COLUMN_NAME DATA_TYPE [, ...]
)
USING iceberg
WITH (
    uri = 'LOCATION_URI'
);

다음을 바꿉니다.

  • TABLE_NAME: AlloyDB에서 만들 테이블의 이름입니다.
  • COLUMN_NAME 및 DATA_TYPE: 열 정의입니다. 열 이름과 유형은 기본 Iceberg 테이블의 스키마와 일치해야 합니다.
  • LOCATION_URI: Iceberg 테이블 메타데이터의 위치입니다. 다음 형식 중 하나를 지정합니다.
    • 직접 Cloud Storage 경로: gs://BUCKET_NAME/PATH_TO_ICEBERG_TABLE
    • Lakehouse 런타임 카탈로그 URI: bl://projects/PROJECT_ID/catalogs/CATALOG_NAME/databases/DATABASE_NAME/tables/TABLE_NAME

예시

다음 예시에서는 AlloyDB에서 Iceberg 테이블을 만드는 방법을 보여줍니다.

Cloud Storage 경로에서 테이블 만들기

다음 예시에서는 Cloud Storage 버킷에 있는 Iceberg 데이터 세트에서 지원하는 customer_orders라는 테이블을 만듭니다.

CREATE TABLE customer_orders (
    order_id BIGINT,
    customer_id INT,
    order_status TEXT,
    total_amount DOUBLE PRECISION,
    order_date DATE,
    is_completed BOOLEAN
)
USING iceberg
WITH (
    uri = 'gs://my-iceberg-analytics-bucket/datasets/sales/customer_orders'
);

Lakehouse 런타임 카탈로그에서 테이블 만들기

다음 예시에서는 Lakehouse 런타임 카탈로그에서 관리하는 Iceberg 테이블을 참조하는 테이블을 만듭니다.

CREATE TABLE customer_orders (
    order_id BIGINT,
    customer_id INT,
    order_status TEXT,
    total_amount DOUBLE PRECISION,
    order_date DATE,
    is_completed BOOLEAN
)
USING iceberg
WITH (
    uri = 'bl://projects/my-analytics-project/catalogs/sales_catalog/databases/retail_db/tables/customer_orders'
);

Iceberg 데이터 쿼리

AlloyDB에서 테이블을 만든 후에는 alloydbsuperuser 권한이 있는 표준 SQL SELECT 문을 사용하여 테이블을 쿼리할 수 있습니다. 원하는 경우 GRANT 문을 사용하여 alloydbsuperuser 권한이 없는 사용자에게 읽기 권한을 부여할 수 있습니다. 예를 들면 GRANT SELECT ON customer_orders TO normal_user입니다.

데이터 쿼리

다음 예시에서는 쿼리를 실행하는 방법을 보여줍니다.

SELECT
    customer_id,
    COUNT(order_id) AS total_orders,
    SUM(total_amount) AS total_spent
FROM customer_orders
WHERE is_completed = true
  AND order_date >= '2026-01-01'
GROUP BY customer_id
ORDER BY total_spent DESC
LIMIT 10;

운영 데이터와 조인된 Iceberg 데이터 쿼리

AlloyDB에 있는 실시간 운영 데이터를 Iceberg에 있는 이전 데이터와 결합할 수 있습니다.

SELECT
    c.customer_name,
    c.account_tier,
    COUNT(o.order_id) AS total_orders,
    SUM(o.total_amount) AS historical_spend
FROM customer_orders o
JOIN customers c ON o.customer_id = c.customer_id
WHERE o.is_completed = true
GROUP BY c.customer_name, c.account_tier
ORDER BY historical_spend DESC;

로컬 테이블로 데이터 가져오기

로컬 AlloyDB 스토리지에 Iceberg 데이터의 독립적인 쓰기 가능한 사본을 만들려면 다음 예시와 같이 CREATE TABLE ... AS SELECT를 실행합니다.

CREATE TABLE local_customer_orders AS
SELECT * FROM customer_orders
WHERE order_date >= '2026-01-01';

열 기반 엔진을 사용하여 분석 쿼리 가속화

지연 시간이 매우 짧은 분석 워크로드의 경우 Iceberg 테이블을 AlloyDB 열 기반 엔진 메모리에 직접 채울 수 있습니다.

열 기반 저장소에 Iceberg 테이블 채우기

Iceberg 테이블의 모든 열을 AlloyDB 열 기반 엔진에 채우려면 google_columnar_engine_add() 함수를 사용합니다. 예를 들면 다음과 같습니다.

SELECT google_columnar_engine_add('customer_orders');

쿼리에서 사용하는 특정 열만 채우려면 쉼표로 구분된 열 이름 목록을 두 번째 인수로 전달합니다. 예를 들면 다음과 같습니다.

SELECT google_columnar_engine_add('customer_orders', 'customer_id,order_status');

자세한 내용은 SQL 함수를 사용하여 열 추가를 참조하세요.

채워진 데이터 새로고침

기본 Iceberg 데이터 세트에 새 스냅샷을 작성하는 경우 테이블을 새로고침하여 최신 데이터를 열 기반 엔진에 다시 로드하여 쿼리가 최신 결과를 반환하도록 합니다.

SELECT google_columnar_engine_refresh('customer_orders');

열 형식 저장소에서 테이블 삭제

열 형식 저장소에서 Iceberg 테이블을 삭제하고 직접 스캔으로 되돌리려면 다음 안내를 따르세요.

SELECT google_columnar_engine_drop('customer_orders');

쿼리 실행 모니터링 및 확인

AlloyDB가 Iceberg 테이블에 대해 쿼리를 실행하는 방식을 모니터링하고 쿼리가 인메모리 열 기반 엔진을 사용하는지 확인할 수 있습니다. 시스템 뷰를 사용하여 캐시 채우기 상태를 확인하고 EXPLAIN를 사용하여 쿼리 실행 계획을 검사합니다.

열 기반 캐싱 상태 확인

Iceberg 테이블이 열 기반 엔진에 채워져 있는지 확인하려면 g_columnar_relations 시스템 뷰를 쿼리합니다.

SELECT relation_name, status
FROM g_columnar_relations
WHERE relation_name = 'customer_orders';

status 값이 USABLE이면 테이블이 열 기반 엔진 메모리에 캐시되었음을 확인합니다.

EXPLAIN로 쿼리 실행 계획 검사

쿼리가 열 기반 엔진을 활용하는지 확인하려면 EXPLAIN 문을 사용합니다.

EXPLAIN (ANALYZE, COSTS OFF)
SELECT SUM(total_amount)
FROM customer_orders
WHERE is_completed = true;

출력은 테이블의 Custom Scan (ColumnarScan) 노드를 통한 열 실행을 나타냅니다.

Custom Scan (ColumnarScan) on customer_orders
  Filter: (is_completed = true)

문제 해결

이 섹션에서는 AlloyDB에서 Iceberg 테이블을 구성하고 쿼리할 때 발생하는 일반적인 문제를 해결하는 방법을 설명합니다.

google_columnar_engine.enable_iceberg_reads 플래그가 사용 중지됨

원인: Iceberg 직접 액세스를 위한 데이터베이스 플래그가 사용 중지되었습니다.

권장 해결 방법: 인스턴스에서 데이터베이스 플래그 google_columnar_engine.enabled=on 및 google_columnar_engine.enable_iceberg_reads=on를 설정하고 인스턴스를 다시 시작합니다.

Cloud Storage에 대한 액세스 권한이 거부되었습니다.

원인: AlloyDB 클러스터 서비스 계정에 Cloud Storage 버킷에 대한 읽기 액세스 권한이 없습니다.

권장 해결 방법: 버킷의 클러스터 서비스 계정에 roles/storage.objectViewer 역할을 부여합니다.

Lakehouse 런타임 카탈로그에 액세스할 때 권한이 거부되었습니다.

원인: AlloyDB 클러스터 서비스 계정에 Lakehouse 런타임 카탈로그에 대한 읽기 액세스 권한이 없습니다.

권장 해결 방법: Lakehouse 런타임 카탈로그를 호스팅하는 Google Cloud 프로젝트의 클러스터 서비스 계정에 roles/biglake.viewer 역할을 부여합니다.

열 기반 채우기 실패

원인: Iceberg 테이블 크기가 열 기반 엔진에서 사용 가능한 메모리 및 SSD 공간을 초과합니다.

권장 해결 방법: 인스턴스에서 google_columnar_engine.memory_size_in_mb 플래그를 사용하여 열 기반 엔진에 할당된 메모리를 늘리거나 google_columnar_engine.storage_cache_size 플래그를 사용하여 열 기반 엔진 스토리지 캐시 크기를 늘립니다. 자세한 내용은 열 기반 엔진의 스토리지 캐시 구성을 참조하세요.

열 기반 엔진 채우기 힙이 가득 참

오류 메시지:

ERROR: Columnar engine population heap is full during population. Set
google_columnar_engine.population_heap_size_in_mb to a bigger value.

원인: 대규모 Parquet 행 그룹을 채우는 데 필요한 메모리가 작업자당 채우기 힙 한도를 초과합니다.

권장 수정사항: 채우기 프로세스에서 더 큰 힙을 사용할 수 있도록 병렬 채우기 작업자 수를 줄입니다. 테이블을 채우는 SQL 세션에서 google_columnar_engine_add() 함수를 호출하기 전에 google_job_scheduler.max_parallel_workers_per_job 플래그를 0로 설정합니다.

SET google_job_scheduler.max_parallel_workers_per_job = 0;
SELECT google_columnar_engine_add('TABLE_NAME');

I can help you with that. Here is the translation of the text you provided: TABLE_NAME을 AlloyDB의 Iceberg 테이블 이름으로 바꿉니다.

다음 단계