Iceberg 는 Spark 확장 형태로 붙는다. Spark 메이저·마이너 버전과 Scala 버전이 정확히 맞는 런타임 jar 을 써야 한다.
org.apache.iceberg:iceberg-spark-runtime-<Spark 메이저.마이너>_<Scala 버전>:<Iceberg 버전>
폐쇄망이면 --packages 대신 jar 을 미리 내려받아 --jars 로 준다. --packages 는 실행 시점에 Maven 저장소로 나가므로 외부 연결이 필요하다.
Iceberg 테이블의 위치를 어떻게 찾는지에 따라 카탈로그 유형이 갈린다.
| 유형 | 메타스토어 | 쓰임 |
|---|---|---|
hadoop |
필요 없음. 웨어하우스 경로 아래 디렉터리 구조로 테이블을 찾는다 | 단독 실험, 파일만 있는 환경 |
hive |
Hive Metastore 에 테이블을 등록한다 | Impala·Hive·Trino 와 같은 테이블을 공유할 때 |
운영에서는 대부분 hive 를 쓴다. 다른 엔진이 같은 테이블을 보려면 메타스토어에 등록돼 있어야 하기 때문이다.
spark-sql \
--jars /opt/jars/iceberg-spark-runtime-3.5_2.12-1.9.0.jar \
--conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
--conf spark.sql.catalog.hdp=org.apache.iceberg.spark.SparkCatalog \
--conf spark.sql.catalog.hdp.type=hadoop \
--conf spark.sql.catalog.hdp.warehouse=hdfs://nameservice1/warehouse/iceberg
SHOW NAMESPACES IN hdp;
SHOW TABLES IN hdp.db1;
SELECT * FROM hdp.db1.events LIMIT 10;
카탈로그 이름(hdp)이 테이블 이름의 첫 부분이 된다. 이름은 자유롭게 정하되 팀 내에서 통일한다.
spark-sql \
--jars /opt/jars/iceberg-spark-runtime-3.5_2.12-1.9.0.jar \
--conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
--conf spark.sql.catalog.ice=org.apache.iceberg.spark.SparkCatalog \
--conf spark.sql.catalog.ice.type=hive \
--conf spark.sql.catalog.ice.uri=thrift://hms-host:9083 \
--conf spark.sql.catalog.ice.warehouse=hdfs://nameservice1/warehouse/tablespace/external/hive
from pyspark.sql import SparkSession
spark = (SparkSession.builder
.appName("iceberg")
.config("spark.jars", "/opt/jars/iceberg-spark-runtime-3.5_2.12-1.9.0.jar")
.config("spark.sql.extensions",
"org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions")
.config("spark.sql.catalog.ice", "org.apache.iceberg.spark.SparkCatalog")
.config("spark.sql.catalog.ice.type", "hive")
.config("spark.sql.catalog.ice.uri", "thrift://hms-host:9083")
.getOrCreate())
spark.sql("SELECT * FROM ice.db1.events LIMIT 10").show()
세션이 이미 만들어진 뒤에는 spark.jars 가 반영되지 않는다. 노트북 커널을 띄우기 전에 설정하거나 커널 정의에 넣어 둔다.
Iceberg 테이블에는 메타데이터 테이블이 함께 붙는다.
SELECT * FROM ice.db1.events.snapshots;
SELECT * FROM ice.db1.events.history;
SELECT * FROM ice.db1.events.files;
SELECT * FROM ice.db1.events VERSION AS OF 3821550127947089009;
SELECT * FROM ice.db1.events TIMESTAMP AS OF '2026-09-01 00:00:00';
| 증상 | 확인할 것 |
|---|---|
ClassNotFoundException: org.apache.iceberg.spark.SparkCatalog |
런타임 jar 이 클래스패스에 없음. cluster 모드면 익스큐터에도 배포됐는지 확인 |
NoSuchMethodError |
Spark 버전과 jar 의 Spark 버전 불일치 |
Table does not exist |
카탈로그 유형 혼동. hive 카탈로그로 만든 테이블은 hadoop 카탈로그에서 보이지 않는다 |
| Impala 와 결과가 다름 | 두 엔진이 서로 다른 스냅샷을 보고 있거나 메타데이터 갱신이 안 된 상태 |
hadoop 카탈로그를 쓰면 같은 데이터가 다른 테이블로 보인다.--jars 로 준 jar 이 익스큐터에도 배포된다. --driver-class-path 만 쓰면 드라이버에서만 로드되어 실행 단계에서 실패한다.