You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SparkSQL执行Hudi表Upsert命令时遭遇数字格式异常问题

Hudi Upsert 执行时触发 NumberFormatException 异常分析与解决

问题现象

在SparkSQL中对Hudi表执行Upsert命令时,抛出HoodieUpsertException,核心错误为java.lang.NumberFormatException: 输入字符串"7df51087"无法转换为数字,涉及的_hoodie_partition_path值为7df51087-9850-4060-b4c3-xxxxxx.parquet。

完整错误栈如下:

org.apache.hudi.exception.HoodieUpsertException: 提交时间20240214115154398的Upsert操作失败
at org.apache.hudi.table.action.commit.BaseWriteHelper.write(BaseWriteHelper.java:74)
at org.apache.hudi.table.action.commit.SparkUpsertCommitActionExecutor.execute(SparkUpsertCommitActionExecutor.java:44)
at org.apache.hudi.table.HoodieSparkCopyOnWriteTable.upsert(HoodieSparkCopyOnWriteTable.java:114)
at org.apache.hudi.table.HoodieSparkCopyOnWriteTable.upsert(HoodieSparkCopyOnWriteTable.java:103)
at org.apache.hudi.client.SparkRDDWriteClient.upsert(SparkRDDWriteClient.java:142)
at org.apache.hudi.DataSourceUtils.doWriteOperation(DataSourceUtils.java:224)
at org.apache.hudi.HoodieSparkSqlWriter$.writeInternal(HoodieSparkSqlWriter.scala:431)
at org.apache.hudi.HoodieSparkSqlWriter$.write(HoodieSparkSqlWriter.scala:132)
at org.apache.spark.sql.hudi.command.InsertIntoHoodieTableCommand$.run(InsertIntoHoodieTableCommand.scala:108)
at org.apache.spark.sql.hudi.command.InsertIntoHoodieTableCommand.run(InsertIntoHoodieTableCommand.scala:61)
at org.apache.spark.sql.execution.command.ExecutedCommandExec.sideEffectResult$lzycompute(commands.scala:75)
at org.apache.spark.sql.execution.command.ExecutedCommandExec.sideEffectResult(commands.scala:73)

根因错误栈:

java.lang.NumberFormatException: 输入字符串"7df51087"无法转换为数字
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.base/java.lang.Integer.parseInt(Integer.java:652)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at org.apache.hudi.index.bucket.BucketIdentifier.bucketIdFromFileId(BucketIdentifier.java:79)
at org.apache.hudi.index.bucket.HoodieSimpleBucketIndex.getLocationMapper(HoodieSimpleBucketInd...

核心根因

Hudi的Simple Bucket Index在解析文件ID时,默认尝试将文件ID的前缀部分(此处为7df51087)按十进制整数解析,但该前缀是十六进制格式的字符串,无法直接转换为十进制整数,因此触发NumberFormatException。

解决方案

  1. 调整Bucket Index的文件ID解析逻辑
    若使用自定义Bucket Index实现,需修改BucketIdentifier.bucketIdFromFileId方法,指定按十六进制解析字符串:

    // 替换原Integer.parseInt(fileIdPrefix)调用
    int bucketId = Integer.parseInt(fileIdPrefix, 16);
    

    若使用Hudi官方版本,建议升级到已修复该问题的版本(如Hudi 0.14.x及后续版本,需验证对应版本的解析逻辑)。

  2. 切换索引类型
    若暂时无法修改或升级Hudi版本,可将表的索引类型从SIMPLE_BUCKET替换为其他兼容类型,例如:

    • BLOOM:基于布隆过滤器的索引,适配多数业务场景
    • GLOBAL_BLOOM:全局布隆索引
    • INMEMORY:内存索引(适合小数据量表)

    修改表属性的示例SQL:

    ALTER TABLE your_hudi_table SET TBLPROPERTIES (
      'hoodie.index.type' = 'BLOOM'
    );
    
  3. 自定义文件ID生成策略
    若必须使用Simple Bucket Index,可通过配置Hudi参数自定义文件ID生成逻辑,确保文件ID前缀为十进制数字。该方式复杂度较高,仅作为备选方案。


内容的提问来源于stack exchange,提问作者SAUMYA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 04:52:52