CDP 에서 행 단위 갱신·삭제가 필요한 워크로드는 저장 형식을 먼저 고른다. 선택지는 Hive 트랜잭션 테이블(ACID), Kudu, Iceberg 세 가지이며 보장 수준과 적합한 쓰임이 다르다. "ACID 를 지원한다" 는 말이 같은 뜻이 아니므로 어느 범위까지 보장되는지를 기준으로 고른다.
| 선택지 | 보장 범위 | 잘 맞는 쓰임 |
|---|---|---|
| Hive 트랜잭션 테이블 | 문장 단위 원자성, 스냅샷 격리, 다중 파티션 갱신 | ETL, 차원 테이블 갱신, 이력 관리 |
| Kudu | 행 단위 연산의 원자성과 강한 일관성. 다중 행·다중 테이블 트랜잭션은 없음 | 실시간 적재와 즉시 조회, 시계열, 대시보드 |
| Iceberg | 스냅샷 기반 테이블 수준 원자성, 타임 트래블 | 데이터 레이크 테이블, 엔진 간 공유 |
CDP 의 Hive 3 에서는 관리 테이블이 기본적으로 트랜잭션 테이블로 만들어진다. CDH 나 HDP 에서 올라온 환경에서는 CREATE TABLE 의 기본 동작이 바뀌었다는 점을 먼저 확인한다.
전체 ACID(갱신·삭제 가능) 테이블은 ORC 로 저장한다. insert-only 트랜잭션 테이블은 다른 포맷도 허용된다.
CREATE TABLE mydb.my_acid_table (
id BIGINT,
name STRING,
updated_at TIMESTAMP
)
STORED AS ORC
TBLPROPERTIES ('transactional'='true');
Hive 3 의 전체 ACID 테이블은 버킷팅을 요구하지 않는다. 버킷이 필수라는 설명은 Hive 2 시절 기준이다.
INSERT INTO mydb.my_acid_table VALUES (1, 'John', current_timestamp());
UPDATE mydb.my_acid_table SET name = 'Johnny' WHERE id = 1;
DELETE FROM mydb.my_acid_table WHERE id = 1;
갱신과 삭제는 델타 파일을 만든다. 델타가 쌓이면 읽기 성능이 떨어지므로 컴팩션이 도는지 확인하는 것이 운영의 핵심이다. Cloudera Manager 의 Hive 설정에서 컴팩션 이니시에이터와 워커 스레드가 켜져 있어야 하고, 워커 수가 부족하면 밀린다.
트랜잭션 관련 핵심 설정은 다음과 같다. CDP 에서는 기본값으로 켜져 있으나 값이 바뀌어 있지 않은지 확인할 때 쓴다.
<property>
<name>hive.support.concurrency</name>
<value>true</value>
</property>
<property>
<name>hive.txn.manager</name>
<value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
</property>
<property>
<name>hive.compactor.initiator.on</name>
<value>true</value>
</property>
<property>
<name>hive.compactor.worker.threads</name>
<value>2</value>
</property>
hive.txn.timeout 은 트랜잭션이 하트비트를 보내지 않고 방치될 수 있는 시간이며 기본값은 300초다. 이 시간을 넘기면 중단 처리된다. 길게 도는 작업 때문에 늘려야 할 때가 있지만, 너무 늘리면 죽은 트랜잭션이 잠금을 오래 쥔다.
메타스토어는 RDBMS 로 받쳐야 한다. 트랜잭션 상태와 잠금이 전부 메타스토어 DB 에 들어가므로 이 DB 의 성능이 곧 트랜잭션 처리량이 된다.
Kudu 는 기본 키가 있는 테이블에 행 단위 삽입·갱신·삭제를 빠르게 처리한다. Impala 에서 SQL 로 다룬다.
CREATE TABLE transactions (
transaction_id BIGINT,
customer_id STRING,
amount DOUBLE,
updated_at TIMESTAMP,
PRIMARY KEY (transaction_id)
)
PARTITION BY HASH(transaction_id) PARTITIONS 8
STORED AS KUDU;
보장되는 것과 아닌 것을 나눠 보면 다음과 같다.
| 항목 | 지원 |
|---|---|
| 기본 키 제약 | 지원. 필수다 |
| 단일 행 연산의 원자성 | 지원 |
| 복제와 WAL 기반 내구성 | 지원 |
| 여러 행을 묶는 트랜잭션 | 없음 |
| 여러 테이블에 걸친 트랜잭션 | 없음 |
| 롤백 | 없음 |
따라서 "부분 실패 시 전부 되돌린다" 가 요건이면 Kudu 는 맞지 않는다. 반대로 최신 값이 즉시 조회돼야 하는 대시보드·시계열이라면 Hive ACID 보다 낫다.
CDP 7.1.9 이후로 Iceberg 가 Hive · Impala · Spark 에서 공통으로 쓰인다. 스냅샷 단위로 원자적 커밋이 이뤄지고, 버전 2 테이블에서 행 단위 삭제·갱신이 가능하다. 여러 엔진이 같은 테이블을 읽고 쓰는 구성이라면 우선 검토 대상이다. 엔진별로 지원하는 연산 범위가 릴리스마다 달라지므로 사용 중인 런타임 버전의 문서를 대조한다 — 확인 필요.
Impala 는 Hive 의 insert-only 트랜잭션 테이블을 읽고 쓸 수 있고, 전체 ACID 테이블은 읽기가 가능하다. 쓰기 지원 범위는 런타임 버전에 따라 다르므로 대조가 필요하다 — 확인 필요.
Spark 에서 Hive 트랜잭션 테이블에 접근할 때는 Hive Warehouse Connector 를 쓴다. 파일을 직접 읽으면 델타 파일 구조를 해석하지 못해 잘못된 결과가 나온다.