본문 바로가기

Hadoop/Hudi

[Apache Hudi] 2. 파일 구조

Apache hudi는 DFS에 파일 형태로 저장된다.
테이블 타입에 따라 parquet 파일로만 저장이 되기도하고, parquet + avro로 저장이 되기도 하는데, 먼저 DFS에 어떠한 구조로 저장이 되는지, 각 파일은 어떠한 형태를 띄는지 정리해보도록 하자.

BasePath

Hudi Table의 데이터가 저장되는 root path이다. 해당 경로 하위로 각종 메타 디렉토리, 파티션 디렉토리등이 생성이 된다.

public class InsertDataApp {
    private static final String tableName= "hudi_trips_cow";
    private static final String basePath = "file:///tmp/hudi_trips_cow";  //테스트로 로컬위지에 저장

    public static void main(String[] args) throws IOException {
        QuickstartUtils.DataGenerator dg = new QuickstartUtils.DataGenerator();

        SparkSession spark = SparkSession.builder()
                                            .master("local[*]")
                                            .appName("spark-hudi-first-app")
                                            .config("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
                                            .getOrCreate();
        JavaSparkContext sc = new JavaSparkContext(spark.sparkContext());

        List<String> data = QuickstartUtils.convertToStringList(dg.generateInserts(2)) ;
        Dataset<Row> df =  spark.read().json(sc.parallelize(data, 2));

        df.write().format("hudi")
               .options(QuickstartUtils.getQuickstartWriteConfigs())
               .option(PRECOMBINE_FIELD_OPT_KEY(), "ts")
               .option(RECORDKEY_FIELD_OPT_KEY(), "uuid")
               .option(PARTITIONPATH_FIELD_OPT_KEY(), "partitionpath")
               .option(TABLE_NAME, tableName)
               .mode(SaveMode.Overwrite)
               .save(basePath);			//basepath에 테이블 데이터 저장

    }
}

위와 같은 Spark 코드로 로컬에 임시 테이블을 생성해 보면 간단하게 basepath의 구조를 파악할 수 있다.

이렇게 저장된 데이터를 출력해보면 아래와 같다.(아래 내용과 partitionpath컬럼이 연관되어있으니 유심히 살펴보고 넘어가자)

Base Path 구조

/tmp/hudi_trips_cow
ㄴ .hoodie
ㄴ americas
  ㄴ brazil
    ㄴ sao_paulo
      ㄴ 9d92af43-52cf-4dfd-8551-fa514f2fe100-0_0-28-26_20220118051719645.parquet (parquet file)
      ㄴ .9d92af43-52cf-4dfd-8551-fa514f2fe100-0_20220118051719645.log.1_0-28-29 (avro file)
  • .hoodie: timeline 데이터가 저장이 되는 위치
  • 나머지 디렉토리: Spark 코드상에 "PARTITIONPATH_FIELD_OPT_KEY(캡쳐의 partitionpath)"로 지정한 값을 디렉토리로 나눠 저장한다.
    앞으로 논하겠지만, Table Type에 따라 parquet 파일만 생성되기도하고, parquet + avro file이 생성되기도 한다.

File Group과 File Id

각 파티션 디렉토리 별로 파일 그룹이 생성되며, 파일 그룹안에는 file Id로 구분되는 파일들이 존재하게 된다.

File 이름 규칙

1) Base File(parquet)

2) log File(avro)

File Slices

각 파일 그룹에는 여러 개의 파일 슬라이스가 포함되어 있으며, 각 슬라이스에는 로그 파일(*.log)과 함께 특정 커밋/압축 인스턴트 시간에 생성된 Base file(*.parquet)이 포함되어 있다. 

결과적으로

Base path > Partition > File Groups > File Slices 

라고 보면 되겠다.