hive0.11的hive server实现kerberos认证和impersonation中碰到的问题
背景最近在做hive0.9升级到0.11的工作,其中一个步骤就是将之前apply到0.9的patch re-apply到0.11中,有一个patch(https://github.com/lalaguozhe/hive/commit/f2892f9e4706f3ea04117cbc7e7f54ff6af1e415)参考了hive metastore service的实现,对hive server增加了sasl kerberos认证,支持impersonate成client ugi的身份来启动作业(默认方式会以起hive service daemon的用户身份来执行,导致所有query共用一个用户启动作业)。
发现的问题不过在re-apply这个patch后发现,用jdbc client访问hive server对于某些语句返回的是空结果集(HiveQueryResultSet中的fetchedRows是个空集合),中间也没有任何报错。非常奇怪,通过多次尝试定位出只有一种case的语句会正常返回结果,即类似“select * from xxx where yyy”这种不会起MapReduce Job的语句,其他“show tables/databases”,“select a from xxx”等语句都返回为空结果集。
调研
Hive jdbc client(底层是thrift client)在提交一条语句的时候会经历如下过程:1. 构建execute_args对象,里面封装了要执行的语句,发送远程方法名execute和execute_args对象,接收execute返回结果,这时候client已经获取了column names和column types信息。
2. 类似”show tables/databases“这种DDL/DML语句,这种语句会先在本地FileSystem上创建一个scratch目录(由hive.exec.local.scratchdir配置),将计算结果写到本地scratch目录下,再通过FetchTask读取
3. 类似”select count(1) from tblname“这种会起MR Job的语句,会先在HDFS上创建scratch目录(由hive.exec.scratchdir配置),计算结果写到hdfs scratch目录下,再通过FetchTask读出来。
尝试多次后发现第一种类型的语句能返回结果,第二种第三种类型语句返回为空集合,而两者区别就在于是直接读取原表数据路径还是从scratch目录中读取。
HIVE在Compile环节会设置环境Context,创建local/hdfs scratch目录。在0.10版本之前,会存在一个问题,如果用户强制kill掉正在执行的语句,那么这些scratch dir就变成orphaned dir,未被清理。HIVE在0.10中加入了HIVE-3251来解决这个问题。Driver中设置Context的HDFSCleanUp为truepublic void close() throws HiveSQLException { try { acquire(); ShimLoader.getHadoopShims().closeAllForUGI(sessionUgi); cancelDelegationToken(); } finally { release(); super.close(); } }
解决方法了解实现原理后,解决的方式有三种:1. 启动Hive Server的时候关闭FileSystem Cachepublic void clean() { if (driver != null) { driver.close(); driver.destroy(); } SessionState session = SessionState.get(); if (session.getTmpOutputFile() != null) { session.getTmpOutputFile().delete(); } pipeIn = null; try { LOG.info("Start to close filesystem for ugi:" + UserGroupInformation.getCurrentUser().getUserName()); ShimLoader.getHadoopShims().closeAllForUGI(UserGroupInformation.getCurrentUser()); } catch (IOException ioe) { ioe.printStackTrace(); } }
修改上述代码后重新编译,之前三种case语句都能正常返回结果了,就这个问题折腾了一天,hive的bug不是一般的多啊,所以时不时会踩到坑,不过在发现问题到debug再到解决问题的过程中也学习到了很多。
本文链接http://blog.csdn.net/lalaguozhe/article/details/12969379,转载请注明