更新时间:2024-05-28 GMT+08:00

Hudi表模型设计规范

规则

  • Hudi表必须设置合理的主键。

    Hudi表提供了数据更新和幂等写入能力,该能力要求Hudi表必须设置主键,主键设置不合理会导致数据重复。主键可以为单一主键也可以为复合主键,两种主键类型均要求主键不能有null值和空值,可以参考以下示例设置主键:

    SparkSQL:

    // 通过primaryKey指定主键,如果是复合主键需要用逗号分隔
    create table hudi_table (
    id1 int,
    id2 int,
    name string,
    price double
    ) using hudi
    options (
    primaryKey = 'id1,id2',
    preCombineField = 'price'
    );

    SparkDatasource:

    // 通过hoodie.datasource.write.recordkey.field指定主键
    df.write.format("hudi").
    option("hoodie.datasource.write.table.type", COPY_ON_WRITE).
    option("hoodie.datasource.write.precombine.field", "price").
    option("hoodie.datasource.write.recordkey.field", "id1,id2").
    

    FlinkSQL:

    // 通过hoodie.datasource.write.recordkey.field指定主键
    create table hudi_table(
    id1 int,
    id2 int,
    name string,
    price double
    ) partitioned by (name) with (
    'connector' = 'hudi',
    'hoodie.datasource.write.recordkey.field' = 'id1,id2',
    'write.precombine.field' = 'price')
  • Hudi表必须配置precombine字段。

    在数据同步过程中不可避免会出现数据重复写入、数据乱序问题,例如:异常数据恢复、写入程序异常重启等场景。通过设置合理precombine字段值可以保证数据的准确性,老数据不会覆盖新数据,也就是幂等写入能力。该字段可用选择的类型包括:业务表中更新时间戳、数据库的提交时间戳等。precombine字段不能有null值和空值,可以参考以下示例设置precombine字段:

    SparkSQL:

    //通过preCombineField指定precombine字段
    create table hudi_table (
    id1 int,
    id2 int,
    name string,
    price double
    ) using hudi
    options (
    primaryKey = 'id1,id2',
    preCombineField = 'price'
    );

    SparkDatasource:

    //通过hoodie.datasource.write.precombine.field指定precombine字段
    df.write.format("hudi").
    option("hoodie.datasource.write.table.type", COPY_ON_WRITE).
    option("hoodie.datasource.write.precombine.field", "price").
    option("hoodie.datasource.write.recordkey.field", "id1,id2").
    

    Flink:

    //通过write.precombine.field指定precombine字段
    create table hudi_table(
    id1 int,
    id2 int,
    name string,
    price double
    ) partitioned by (name) with (
    'connector' = 'hudi',
    'hoodie.datasource.write.recordkey.field' = 'id1,id2',
    'write.precombine.field' = 'price')
  • 流式计算采用MOR表。

    流式计算为低时延的实时计算,需要高性能的流式读写能力,在Hudi表中存在的MOR和COW两种模型中,MOR表的流式读写性能相对较好,因此在流式计算场景下采用MOR表模型。关于MOR表在读写性能的对比关系如下:

    对比维度

    MOR表

    COW表

    流式写

    流式读

    批量写

    批量读

  • 实时入湖,表模型采用MOR表。

    实时入湖一般的性能要求都在分钟内或者分钟级,结合Hudi两种表模型的对比,因此在实时入湖场景中需要选择MOR表模型。

  • Hudi表名以及列名采用小写字母。

    多引擎读写同一张Hudi表时,为了规避引擎之间大小写的支持不同,统一采用小写字母。

建议

  • Spark批处理场景,对写入时延要求不高的场景,采用COW表。

    COW表模型中,写入数据存在写放大问题,因此写入速度较慢;但COW具有非常好的读取性能力。而且批量计算对写入时延不是很敏感,因此可以采用COW表。

  • Hudi表的写任务要开启Hive元数据同步功能。

    SparkSQL天然与Hive集成,无需考虑元数据问题。该条建议针对的是通过Spark Datasource API或者Flin写Hudi表的场景,通过这两种方式写Hudi时需要增加向Hive同步元数据的配置项;该配置的目的是将Hudi表的元数据统一托管到Hive元数据服务中,为后续的跨引擎操作数据以及数据管理提供便利。