1. 引入

线上用户反馈使用Presto查询Hudi表泛起错误,而将Hudi表的文件单独建立parquet类型表时查询无任何问题,要害报错信息如下

40931f6e-3422-4ffd-a692-6c70f75c9380-0_0-384-2545_20200513165135.parquet, start=0, length=67108864, fileSize=67108864, hosts=[], forceLocalScheduling=false, partitionName=dt=2020-05-08, s3SelectPushdownEnabled=false} (start = 2.3651547291593433E10, wall = 163 ms, cpu = 0 ms, wait = 0 ms, calls = 1): HIVE_BAD_DATA: Not valid Parquet file: 

报Hudi表中文件花样不是正当的parquet花样错误。

2. 问题复现

最先凭据用户提供的信息,模拟线上Hudi数据集巨细、Presto和Hudi版本(0.5.2-incubating)来复现该问题。

举行试验发现当Hudi表单文件巨细较小时,使用Presto查询一切正常。

构建Hudi表中单文件巨细为100MB以上数据集,使用Presto查询。

可以看到,当Hudi数据集中文件巨细为100MB时复现了Not Valid Parquet file异常,通过Presto的web ui可以看到详细的错误客栈如下

通过错误客栈可以进一步确认在读取parquet文件时校验失败,最先嫌疑parquet文件确实被损坏,但使用parquet-tools工具检查内陆parquet文件,发现无问题。

3. 问题排查

经由上述步骤复现了问题,问题能够复现就好排查。但Presto对于正当parquet文件检查为何会报错?带着这个疑问最先在内陆debug Presto,首先在Presto服务端和IDEA中举行响应的设置。

3.1 Presto服务端设置

要想能够毗邻到Presto服务端,需要在PRESTO_HOME根目录下建立etc目录,然后建立jvm.properties文件,内容如下

-server
-Xmx8G
-XX:+UseG1GC
-XX:G1HeapRegionSize=32M
-XX:+UseGCOverheadLimit
-XX:+ExplicitGCInvokesConcurrent
-XX:+HeapDumpOnOutOfMemoryError
-XX:+ExitOnOutOfMemoryError
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
-XX:+TraceClassLoading
-XX:+TraceClassUnloading
-verbose:class

上述设置除了可以毗邻服务端举行debug外,添加的-XX:+TraceClassLoading-XX:+TraceClassUnloading两个设置项,还会打印每个类加载和卸载的日志(这个在排查presto类加载器问题时异常有用,建议开启)。

3.2 IDEA设置

设置完Presto服务端后,在IDEA举行如下设置即可。

约搏牛牛大吃小:填坑!线上Presto查询Hudi表异常排查  第1张

3.3 单步调试

IDEA中开启了debug后,通过Presto客户端查询时(select * from hudi_big_table),就可以举行单步调试,首先我们在BackgroundHiveSplitLoader类中打了些断点(该类是加载Split的要害类)。

约搏牛牛大吃小:填坑!线上Presto查询Hudi表异常排查  第2张

通过shouldUseFileSplitsFromInputFormat方式判断是否直接通过注解(@UseFileSplitsFromInputFormat)获取FileSplit。Hudi与外部系统交互的HoodieParquetInputFormatHoodieParquetRealtimeInputFormat两个类都使用了该注解。

从上图可以看到100MB的文件被分成了四个InputSplit(根据32MB巨细举行切分),后续Presto会凭据InputSplit来组织对应的InternalHiveSplit

进一步在异常客栈地方打断点如下

约搏牛牛大吃小:填坑!线上Presto查询Hudi表异常排查  第3张

凭据上述代码逻辑可知,从文件中读取magic与parquet文件的MAGIC不相等导致抛出了异常。

值得注意的是fileSize的巨细为33554432,示意一个InputSplit的巨细,而并非文件巨细,因此获取metadataLength时并不准确,导致并非读取了parquet文件的magic,而是读取了InputSplit的数据,因此校验时抛出异常。理论上对于差别的InputSplit,该方式传入的fileSize巨细应该即是文件的巨细,而非InputSplit的巨细,那么这个fileSize的巨细是在哪个步骤通报错误的呢?带着这个疑问,继续举行debug。

凭据前面debug信息得知Presto会通过InputSplit建立InternalHiveSplit,继续debug天生InternalHiveSplit的逻辑

约搏牛牛大吃小:填坑!线上Presto查询Hudi表异常排查  第4张

可以看到在上面组织InternalHiveSplit时,通报的参数值为start=0、start + length=33554432,length=33554432,而InternalHiveSplit自己的参数对应为start、end、fileSize,可以看到错误地将length当成fileSize通报了

既然嫌疑这个参数通报错误导致了异常,那么修改参数为fileSize后是否可以修复该问题?于是打包验证考察异常是否还会泛起,即对presto-hive模块重新打包,放入$PRESTO_HOME/plugin/presto-hive目录中,重启Presto服务,再次举行验证。

约搏牛牛大吃小:填坑!线上Presto查询Hudi表异常排查  第5张

可以看到修改参数后,查询一切正常!!!

另外对Hudi的小文件也举行了回归测试,查询也正常!自此可以发现是由于参数纰谬的bug导致了异常,鉴于这个bug对Presto社区其他用户也可能产生影响,于是查看Presto的master分支是否修复了该问题,若未修复,可将该patch回推到社区,于是查看了Presto的master分支对应代码,发现已经有开发者修复了!

约搏牛牛大吃小:填坑!线上Presto查询Hudi表异常排查  第6张

找到对应的PR:https://github.com/prestodb/presto/pull/14355(也仅仅只是修改了上述的一行代码),在4月7号合入master分支,从这个PR得知,该bug是由https://github.com/prestodb/presto/pull/12780引入。

3.4 影响的版本

由于该缺陷是在2019年5月引入Presto社区,在2020年4月得以修复,时代公布的版本(0.221 ~ 0.235)都市受到影响,如内陆测试0.227、0.231版本都有问题。最近社区公布了0.236版本修复了该问题,若是生产环境使用的版本在0.221 ~ 0.235之间,建议升级或者cherry-pick对应的patch。

4. 总结

凭据线上用户反馈查询Hudi表问题,由于线上环境欠好debug,需凭据上线环境在内陆模拟复现问题,然后快速debug排查修复问题。固然本篇文章省略了debug的旁路路径,只给出了debug的要害路径。

,

SuNBet

www.0379st.com信誉来自于每一位客户的口碑,Sunbet贴心的服务,让你尊享贵宾通道,秒速提现,秒速到账,同行业中体验最佳。

发布评论

分享到:

晋城城区网:理文指港超善后不公 入信抗新政
1 条回复
  1. 欧博APP下载
    欧博APP下载
    (2020-07-30 00:00:12) 1#

    Allbet Gmaing开户欢迎进入Allbet Gmaing开户(www.aLLbetgame.us):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。找了好久,心心念念的

发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。