Hive on tez的insert union 子目录的问题【使用tez插入,mr疫情无法查询到数据】
hive tez insert union all问题
问题描述
在hive中使用tez模式时,发现tez的输出结果在对应表目录中,生成了子目录,造成未配置tez的hive客户端对该表进行读取时,无法获取到数据。
检查表的输出目录,在分区目录下发现了两个子目录:1和2:
/user/hive/test1/20170920000000/1
/user/hive/test1/20170920000000/2
原因
查看对应的sql,发现存在insert union操作,查看往上信息,发现tez对于insert union操作会进行优化,通过并行加快速度,为防止有相同文件输出,所以对并行的输出各自生成成了一个子目录,在子目录中存放结果。如果此时全部hive客户端引擎及相关都设定为tez,则无问题。如果有客户端还在使用mr引擎,则会出现读取不到数据的情况。而在hive中,对于表目录存放信息有如下策略:
在Hive默认设置中,hive只能读取对应表目录下的文件,
1)如果表目录中同时存在目录和文件
则使用hive进行读取时,会报目录非文件的错误
2)表目录中只有目录
hive不会进行深层递归查询,只会读取到对应查询目录,会查询结果为空
3)表目录中只有文件
则可以正常查询
Hive on tez 中对insert union操作进行了优化,会并行输出到对应的表目录,为防止有相同名文件存在,所以为各自输出在表目录下各自设置了一个目录,里边存放执行结果
此种目录,对tez引擎客户端可读。但是对于mr引擎,因为其只会便遍历到对应分区层。发现分区下没有文件后,就返回空
解决思路
发现该现象后,从网上搜索解决方案,http://grokbase.com/t/hive/user/162r80a2g9/anyway-to-avoid-creating-subdirectories-by-insert-with-union
经该文章提示,可以开启mapreduce的递归查询模式:
set mapreduce.input.fileinputformat.input.dir.recursive=true
在hive中,设置执行查询后,会提示错误,要求将set hive.mapred.supports.subdirectories=true;
经过两个set后,仔执行查询,hive即可对tez引擎产union产出的数据进行访问。
同时为了查看tez的此种情况对其他引擎的兼容性,又对sparktThriftServer的sql访问进行了测试:
对于sparkthriftserver,只需添加set mapreduce.input.fileinputformat.input.dir.recursive=true ,即可访问对应数据
总结一下sparkThriftServer模式与hive的不同
1)在表目录下同时有文件和目录时(非分区目录)
此时sparkThriftServer和hive都会报非文件错误
2)在表目录下均为目录(非分区目录)
此时sparkThriftServer会报非文件错误,hive无错,但是查询为空
解决方案
方案一:所有hive端都替换为tez引擎
这不会出现上述问题,但会存在对其他引擎如spqrk,mr,presto等的影响
方案二:为hadoop和hive设置可递归读
该方案相对可行,但需要调研对普通mr任务的影响
解决方案来自:https://blog.csdn.net/myg821561935/article/details/78071014
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别
丞旭猿论坛
暂无评论内容