스파크 시작하기

스파크 시작하기 (Getting Started)

아이스버그의 최신 버전은 1.11.0이에요. 스파크는 현재 아이스버그 연산에 가장 풍부한 기능을 제공하는 컴퓨트 엔진이에요. 이 문서에서는 스파크 셸에서 아이스버그를 시작하는 방법과 카탈로그 추가, 테이블 생성, 쓰기, 읽기까지 기본적인 사용법을 예시와 함께 알려드릴게요. 스파크로 아이스버그 개념과 기능을 익히는 것을 권장해요.

출처: 문서

본문

아이스버그의 최신 버전은 1.11.0이에요.

스파크는 현재 아이스버그 연산에 가장 기능이 풍부한 컴퓨트 엔진이에요. 아이스버그 개념과 기능을 예시와 함께 이해하려면 스파크로 시작하는 것을 권장해요. 다른 컴퓨트 엔진에서 아이스버그를 사용하는 문서는 다중 엔진 지원(Multi-Engine Support) 페이지에서 볼 수 있어요.

스파크에서 아이스버그 사용하기 (Using Iceberg in Spark)

스파크 셸에서 아이스버그를 사용하려면 --packages 옵션을 사용해요.

spark-shell --packages org.apache.iceberg:iceberg-spark-runtime-4.1_2.13:1.11.0

정보 (Info)

아이스버그를 스파크 설치에 포함시키고 싶다면 iceberg-spark-runtime-4.1_2.13 Jar를 스파크의 jars 폴더에 추가해주세요.

카탈로그 추가 (Adding catalogs)

아이스버그에는 SQL 명령이 테이블을 관리하고 이름으로 로드할 수 있게 해주는 카탈로그가 포함돼 있어요. 카탈로그는 spark.sql.catalog.(catalog_name) 아래의 속성을 사용해서 구성해요.

이 명령은 $PWD/warehouse 아래의 테이블을 위한 local이라는 경로 기반 카탈로그를 만들고, 아이스버그 테이블 지원을 스파크의 내장 카탈로그에 추가해요.

spark-sql --packages org.apache.iceberg:iceberg-spark-runtime-4.1_2.13:1.11.0\
    --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
    --conf spark.sql.catalog.spark_catalog=org.apache.iceberg.spark.SparkSessionCatalog \
    --conf spark.sql.catalog.spark_catalog.type=hive \
    --conf spark.sql.catalog.local=org.apache.iceberg.spark.SparkCatalog \
    --conf spark.sql.catalog.local.type=hadoop \
    --conf spark.sql.catalog.local.warehouse=$PWD/warehouse

테이블 생성 (Creating a table)

스파크에서 첫 아이스버그 테이블을 만들려면 spark-sql 셸이나 spark.sql(...)로 CREATE TABLE 명령을 실행해요.

-- local is the path-based catalog defined above
CREATE TABLE local.db.table (id bigint, data string) USING iceberg;
CREATE TABLE source (id bigint, data string) USING parquet;
CREATE TABLE updates (id bigint, data string) USING parquet;

아이스버그 카탈로그는 다음을 포함해 전체 SQL DDL 명령 범위를 지원해요.

  • CREATE TABLE ... PARTITIONED BY
  • CREATE TABLE ... AS SELECT
  • ALTER TABLE
  • DROP TABLE

쓰기 (Writing)

테이블이 만들어지면 INSERT INTO로 데이터를 삽입해요.

INSERT INTO local.db.table VALUES (1, 'a'), (2, 'b'), (3, 'c');
INSERT INTO source VALUES (10, 'd'), (11, 'ee');
INSERT INTO updates VALUES (1, 'x'), (2, 'x'), (4, 'z');
INSERT INTO local.db.table SELECT id, data FROM source WHERE length(data) = 1;

아이스버그는 스파크에 행 수준 SQL 업데이트인 MERGE INTO와 DELETE FROM도 추가해요.

MERGE INTO local.db.table t USING (SELECT * FROM updates) u ON t.id = u.id
WHEN MATCHED THEN UPDATE SET t.data = u.data
WHEN NOT MATCHED THEN INSERT *;

아이스버그는 새 v2 DataFrame 쓰기 API로 DataFrame 쓰기를 지원해요.

spark.table("source").select("id", "data")
     .writeTo("local.db.table").append()

기존 쓰기 API도 지원되지만 권장되지는 않아요.

읽기 (Reading)

SQL로 읽으려면 SELECT 쿼리에서 아이스버그 테이블의 이름을 사용해요.

SELECT count(1) as count, data
FROM local.db.table
GROUP BY data;

SQL은 테이블을 검사하는 데도 권장되는 방법이에요. 테이블의 모든 스냅샷을 보려면 snapshots 메타데이터 테이블을 사용해요.

SELECT * FROM local.db.table.snapshots;

+-------------------------+----------------+-----------+-----------+----------------------------------------------------+-----+
| committed_at            | snapshot_id    | parent_id | operation | manifest_list                                      | ... |
+-------------------------+----------------+-----------+-----------+----------------------------------------------------+-----+
| 2019-02-08 03:29:51.215 | 57897183625154 | null      | append    | s3://.../table/metadata/snap-57897183625154-1.avro | ... |
|                         |                |           |           |                                                    | ... |
|                         |                |           |           |                                                    | ... |
| ...                     | ...            | ...       | ...       | ...                                                | ... |
+-------------------------+----------------+-----------+-----------+----------------------------------------------------+-----+

DataFrame 읽기가 지원되며 이제 spark.table로 이름으로 테이블을 참조할 수 있어요.

val df = spark.table("local.db.table")
df.count()

타입 호환성 (Type compatibility)

스파크와 아이스버그는 서로 다른 타입 집합을 지원해요. 아이스버그는 타입 변환을 자동으로 하지만 모든 조합에 대해서는 아니므로, 테이블의 컬럼 타입을 설계하기 전에 아이스버그의 타입 변환을 이해하는 것이 좋아요.

스파크 타입을 아이스버그 타입으로 (Spark type to Iceberg type)

이 타입 변환 표는 스파크 타입이 아이스버그 타입으로 어떻게 변환되는지 설명해요. 이 변환은 아이스버그 테이블 생성과 스파크를 통한 아이스버그 테이블 쓰기 모두에 적용돼요.

Spark Iceberg 참고
boolean boolean
short integer
byte integer
integer integer
long long
float float
double double
date date
timestamp timestamp with timezone
timestamp_ntz timestamp without timezone
char string
varchar string
string string
binary binary
decimal decimal
struct struct
array list
map map

정보 (Info)

이 표는 테이블 생성 중 대표적인 변환을 기준으로 해요. 실제로는 쓰기에서 더 넓은 지원이 적용돼요. 쓰기에 대한 몇 가지 포인트는 다음과 같아요.

  • 아이스버그 숫자 타입(integer, long, float, double, decimal)은 쓰기 중 승격(promotion)을 지원해요. 예를 들어 스파크 타입 short, byte, integer, long을 아이스버그 타입 long으로 쓸 수 있어요.
  • 아이스버그 fixed 타입에는 스파크 binary 타입으로 쓸 수 있어요. 길이에 대한 검증이 수행된다는 점에 유의해주세요.

아이스버그 타입을 스파크 타입으로 (Iceberg type to Spark type)

이 타입 변환 표는 아이스버그 타입이 스파크 타입으로 어떻게 변환되는지 설명해요. 이 변환은 스파크를 통한 아이스버그 테이블 읽기에 적용돼요.

Iceberg Spark 참고
boolean boolean
integer integer
long long
float float
double double
date date
time 지원되지 않음
timestamp with timezone timestamp
timestamp without timezone timestamp_ntz
string string
uuid string
fixed binary
binary binary
decimal decimal
struct struct
list array
map map
nanosecond timestamp 지원되지 않음
nanosecond timestamp with timezone 지원되지 않음
unknown null Spark 4.0+
variant variant Spark 4.0+
geometry 지원되지 않음
geography 지원되지 않음

다음 단계 (Next steps)

다음으로 스파크에서 아이스버그 테이블에 대해 더 배울 수 있어요.

  • DDL 명령: CREATE, ALTER, DROP
  • 데이터 쿼리: SELECT 쿼리와 메타데이터 테이블
  • 데이터 쓰기: INSERT INTO와 MERGE INTO
  • 저장 프로시저로 테이블 유지보수

더 알아보기 (Learn more)