【Hudi】基础概念-数据写

数据写

写操作

  • UPSERT:默认行为,数据先通过index打标,有一些启发式算法决定消息的组织以及优化文件的大小==>CDC导入
  • INSERT:跳过index,写入效率更高==>Log Defuplication
  • BULK_INSERT:写顺序,对大数据量的Hudi表初始化友好,对文件的大小限制best offort(写HFile)

写流程(UPSERT)

  • COW

(1)先对 records 按照 record key 去重
(2)首先对这批数据创建索引 (HoodieKey => HoodieRecordLocation);通过索引区分哪些 records 是 update,哪些 records 是 insert(key 第一次写入)
(3)对于 update 消息,会直接找到对应 key 所在的最新 FileSlice 的 base 文件,并做 merge 后写新的 base file (新的 FileSlice)
(4)对于 insert 消息,会扫描当前 partition 的所有 SmallFile(小于一定大小的 base file),然后 merge 写新的 FileSlice;如果没有 SmallFile,直接写新的 FileGroup + FileSlice

  • MOR
    (1)先对 records 按照 record key 去重(可选)
    (2)首先对这批数据创建索引 (HoodieKey => HoodieRecordLocation);通过索引区分哪些 records 是 update,哪些 records 是 insert(key 第一次写入)
    (3)如果是 insert 消息,如果 log file 不可建索引(默认),会尝试 merge 分区内最小的 base file (不包含 log file 的 FileSlice),生成新的 FileSlice;如果没有 base file 就新写一个 FileGroup + FileSlice + base file;如果 log file 可建索引,尝试 append 小的 log file,如果没有就新写一个 FileGroup + FileSlice + base file
    (4)如果是 update 消息,写对应的 file group + file slice,直接 append 最新的 log file(如果碰巧是当前最小的小文件,会 merge base file,生成新的 file slice)
    (5)log file 大小达到阈值会 roll over 一个新的

写流程(Insert)

  • COW
    (1)先对records按照 record key 去重(可选)
    (2)不会创建index
    (3) 如果有小的base file文件,merge base file,生成新的FileSlice+base file,否则直接写新的 FileSlice + base file

  • MOR
    (1)先对records按照 record key 去重(可选)
    (2)不会创建index
    (3) 如果log file可索引,并且有写的FileSlice,尝试追加或写最新的log file;如果log file不可索引,写一个新的 FileSlice+base file.

写流程(Insert Overwrite)

在同一个分区中创建新的文件组集。现有的文件组被标记为"删除"。根据最新记录的数据创建新的文件组。

  • COW
    在这里插入图片描述
  • MOR
    在这里插入图片描述

Key生成策略

用来生成HoodileKey+(record key + partition path),目前支持一下策略:

  • 支持多个字段组个record keys
  • 支持多个字段组合的partition path
  • 非分区表

删除策略

1)逻辑删:将value字段全部标记为null
2)物理删:
1、通过OPERATION_OPT_KET删除所有输入记录
2、配置PAYLOAD_CLASS)OPT_KEY=org.apache.hudi.EmptyHoodieRecordPayload 删除所有输入记录
3、在输入记录添加字段L_hoodie_is_deleted

  • 15
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用hudi-spark-client数据hudi表的步骤如下: 1. 首先,创建一个SparkSession对象,并配置相关的Spark和Hudi属性。例如: ```scala val spark = SparkSession.builder() .appName("HudiSparkClientExample") .config("spark.serializer", "org.apache.spark.serializer.KryoSerializer") .config("spark.sql.hive.convertMetastoreParquet", "false") .config("spark.sql.sources.partitionColumnTypeInference.enabled", "false") .config("spark.sql.hive.verifyPartitionPath", "false") .config("spark.hadoop.hive.exec.dynamic.partition.mode", "nonstrict") .config("spark.hadoop.hive.exec.dynamic.partition", "true") .config("spark.sql.warehouse.dir", "hdfs://localhost:9000/user/hive/warehouse") .config("spark.sql.catalogImplementation", "hive") .enableHiveSupport() .getOrCreate() ``` 2. 创建一个DataFrame对象,用于存储要Hudi表的数据。 ```scala val data = Seq( (1, "John Doe", 25), (2, "Jane Smith", 30) ) val df = spark.createDataFrame(data).toDF("id", "name", "age") ``` 3. 使用`HoodieSparkSqlWriter`将DataFrameHudi表。指定要入的表名、要使用的主键列以及要使用的分区列。 ```scala df.write .format("org.apache.hudi") .option("hoodie.table.name", "my_hudi_table") .option("hoodie.datasource.write.precombine.field", "id") .option("hoodie.datasource.write.recordkey.field", "id") .option("hoodie.datasource.write.partitionpath.field", "age") .mode(SaveMode.Append) .save("hdfs://localhost:9000/path/to/hudi_table") ``` 4. 最后,关闭SparkSession对象。 ```scala spark.stop() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值