Hudi目的端的作业执行Spark SQL写入Hudi失败怎么办?
问题描述
原因分析
- 表在metastore中存在,但不是Huid表,或者表在metastore中存在,但是表目录不存在,根因是在表目录下没有.hoodie目录。可能删表的时候只删了文件而没有drop table。
- 设置为主键或者预聚合键的列有空值,写入hoodie会失败。
查看作业配置,查看表属性中hoodie.datasource.write.recordkey.field、hoodie.datasource.write.precombine.field、hoodie.datasource.write.partitionpath.field配置的列在源端数据中是否存在空值。
- 可能数据倾斜导致executor使用内存超出限制,具体原因需要联系MRS定位。Yarn Application ID可以从日志中获取,日志搜索“Yarn Application Id”关键字,查询离报错信息最近的Yarn Application ID即可。
- 登录yarn,根据applicationId查询到yarn任务,打开ApplicationManager。
- 打开stage->查看fail状态的task,通过日志或者界面显示,可以看到失败原因,通常会是以下报错:
transferring unroll memory to storage memory failed(RDD中缓存超过了executor的内存out of memory) 。
- Hudi不支持并发写,会产生commit冲突。
解决方案
- 在DataArts Studio或者Hue或者spark-beeline上执行drop table将表从metastore中删除,然后作业配置 “不存在时创建”重跑作业。或者删除后自己执行建表语句重建一个Hudi表。
对于MOR表来说,删表需要把ro与rt表也同时删除。否则会出现schema残留的问题。
- 删除空值后重跑作业。
- 具体办法:
- 在作业管理界面选择 ,尝试重新执行Spark SQL。
- 通过DataArts Studio执行Spark SQL,设置执行参数或者调整SQL。
set spark.sql.files.maxPartitionBytes=xxM;默认值为128M,可适当调整为64M或者32M。
如果数据切分不均匀,可以修改SQL配置DISTRIBUTE BY rand(),增加一个shuffle过程,打散数据(需要占用较多资源,资源不多时慎用)。
insert into xx select * from xxx DISTRIBUTE BY rand();
- 使用DataArts Studio API方式提交Spark SQL,调大executor内存。
- 排查是否有其他连接在同时写hudi表,如果有,将连接停止,然后CDM作业失败重试。