| 방법 | 적합한 상황 |
|---|---|
| Hive · Impala CTAS | 테이블 단위 변환. 메타스토어에 이미 등록돼 있을 때 |
| Spark | HDFS 경로 단위 변환. 대량 · 반복 작업 |
| NiFi | 흐름 안에서 처리해야 할 때. 단 ORC 읽기는 별도 수단이 필요 |
ORC 와 Parquet 은 둘 다 컬럼 포맷이라 변환의 실익은 압축률보다 엔진 호환성에 있다. Impala 는 Parquet 에 최적화돼 있고 ORC 읽기는 제약이 있다. Hive 는 ORC 쪽이 ACID 를 포함해 기능이 넓다. 변환 전에 어느 엔진이 주로 읽는지부터 정한다.
가장 단순하다. 테이블이 이미 등록돼 있으면 CTAS 한 줄이다.
CREATE TABLE db.tbl_parquet
STORED AS PARQUET
AS SELECT * FROM db.tbl_orc;
파티션 테이블이면 동적 파티션을 켜고 컬럼 순서 마지막에 파티션 키를 둔다.
SET hive.exec.dynamic.partition.mode=nonstrict;
CREATE TABLE db.tbl_parquet (id BIGINT, amt DECIMAL(18,2))
PARTITIONED BY (bse_dt STRING)
STORED AS PARQUET;
INSERT OVERWRITE TABLE db.tbl_parquet PARTITION (bse_dt)
SELECT id, amt, bse_dt FROM db.tbl_orc;
경로만 알면 스키마를 따로 쓸 필요가 없다.
import sys
from pyspark.sql import SparkSession
src, dst = sys.argv[1], sys.argv[2]
spark = SparkSession.builder.appName("orc2parquet").getOrCreate()
(spark.read.orc(src)
.write.mode("overwrite")
.option("compression", "snappy")
.parquet(dst))
spark.stop()
spark-submit --master yarn --deploy-mode cluster orc2parquet.py hdfs:///data/in_orc hdfs:///data/out_parquet
출력 파일이 잘게 쪼개지면 repartition 또는 coalesce 로 파일 수를 줄인다. HDFS 블록 크기(보통 128MB) 언저리를 목표로 한다.
NiFi 의 ConvertRecord 는 RecordReader 와 RecordSetWriter 를 조합해 포맷을 바꾼다. 쓰기 쪽에는 ParquetRecordSetWriter 가 있지만, 표준 배포판에 ORC 를 읽는 RecordReader 는 없다. ORC 를 그대로 읽어 변환하는 흐름은 구성되지 않는다.
현실적인 방법은 두 가지다. NiFi 가 Hive 나 Spark 작업을 호출하도록 하거나(ExecuteStreamCommand, ExecuteSparkInteractive), 애초에 원본을 Avro · JSON 으로 받아 ConvertRecord 로 Parquet 을 쓰고 ORC 는 쓰지 않는 것이다. PutParquet · PutORC 는 쓰기 전용 프로세서라 변환 입력으로는 쓸 수 없다.
ChatGPT 대화에 나오는 OrcReader 컨트롤러 서비스나 Jython 으로 SparkSession 을 만드는 예제는 실제로 동작하지 않는다. NiFi 의 스크립트 엔진은 Jython 이라 PySpark 를 import 할 수 없다.