IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Hive on tez的insert union 子目录的问题【使用tez,mr无法查询到数据】

    admin发表于 2020-03-10 07:48:53
    love 0

    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



沪ICP备19023445号-2号
友情链接