Hive 4 는 Iceberg 를 기본 지원한다. Hive 3 계열(CDP 7.1.7 이상 포함)은 iceberg-hive-runtime jar 가 클래스패스에 있어야 하고, 스토리지 핸들러를 명시한다.
CREATE EXTERNAL TABLE db.tbl (
id BIGINT,
name STRING,
created_at TIMESTAMP
)
PARTITIONED BY (bse_dt STRING)
STORED BY 'org.apache.iceberg.mr.hive.HiveIcebergStorageHandler'
TBLPROPERTIES ('iceberg.catalog'='hive_catalog');
Hive 4 · CDP 최신 계열에서는 축약형을 쓴다.
CREATE TABLE db.tbl (id BIGINT, name STRING)
STORED BY ICEBERG
TBLPROPERTIES ('format-version'='2');
format-version=2 는 행 단위 삭제(merge-on-read)를 쓰기 위한 조건이다. 값을 주지 않으면 버전 1 로 만들어지는 경우가 있으므로 UPDATE · DELETE 가 필요하면 명시한다.
java.lang.ClassNotFoundException: org.apache.iceberg.mr.hive.HiveIcebergInputFormat
jar 가 없거나, 있어도 실행 주체가 못 찾는 경우다. 세션에서 ADD JAR 로 붙이는 방법은 Tez AM 과 태스크까지 전달되지 않아 같은 오류가 반복되기 쉽다.
확실한 해결은 jar 를 HiveServer2 와 Tez 가 함께 보는 위치에 두고 재시작하는 것이다. Cloudera Manager 환경이면 Hive 서비스의 hive.aux.jars.path 또는 auxiliary JAR 경로 설정을 쓴다.
ls /opt/cloudera/parcels/CDH/lib/hive/lib/ | grep -i iceberg
버전을 고를 때는 Hive 버전에 맞는 iceberg-hive-runtime 을 쓴다. Iceberg 런타임 jar 는 Hive · Spark · Flink 용이 따로 있고 서로 바꿔 쓸 수 없다.
Iceberg 는 스냅샷·매니페스트·파일 목록을 메타데이터 테이블로 노출한다.
SELECT * FROM db.tbl.snapshots;
SELECT * FROM db.tbl.history;
SELECT * FROM db.tbl.files;
SELECT * FROM db.tbl.partitions;
행 수만 필요하면 전체 스캔 대신 파일 메타데이터의 합으로 구하는 방법이 있다. 다만 메타데이터 테이블 지원 범위는 엔진과 버전에 따라 다르므로, 쓰기 전에 해당 환경에서 조회되는지 확인이 필요하다.
SELECT SUM(record_count) FROM db.tbl.files;
다른 엔진 문법을 Hive 에 그대로 쓰면 실패한다. 아래는 혼동하기 쉬운 것들이다.
| 문법 | 실제 소속 |
|---|---|
REFRESH TABLE db.tbl |
Spark. Hive 에는 없다 |
CALL system.expire_snapshots(...) |
Spark 프로시저 문법 |
MSCK REPAIR TABLE |
Hive 의 Hive 테이블용. Iceberg 는 디렉터리 스캔으로 파티션을 인식하지 않으므로 의미가 없다 |
Iceberg 는 메타데이터가 곧 파일 목록이므로 외부에서 파일을 디렉터리에 떨어뜨려도 테이블에 반영되지 않는다. 반드시 엔진을 통해 써야 한다.
스냅샷 정리는 Hive 4 에서 ALTER TABLE ... EXECUTE 계열 구문으로 한다. 사용 중인 버전에서 지원하는 구문을 문서로 확인한 뒤 적용한다.
Iceberg 테이블의 COUNT(*) 가 Tez vertex 실패로 끝난다면 원인은 Iceberg 가 아니라 스캔 부담인 경우가 많다. 스냅샷이 쌓이고 작은 파일이 많아지면 태스크 수가 폭증한다. 스냅샷 만료와 데이터 파일 재작성(compaction)을 주기적으로 돌리는 것이 근본 대응이다.
메모리·스큐 대응은 일반 Hive 쿼리와 같다. Hive Tez Vertex failed 진단과 대응 을 참고한다.