Hive在SQL标准权限模式下创建UDF失败的问题排查

Stella981
• 阅读 655

环境:

CDH 5.16

Hive 1.1.0

已开启Kerberos

Hive 授权使用SQL StandardsBased Authorization模式(以下简称SSBA模式)


症状表现:

在编译好UDF的jar包之后,上传到HDFS目录。

hdfs dfs -mkdir /udf

以管理员用户hive,进入beeline客户端。

切换到管理员角色,执行:

set role admin;

提示成功切换角色后,执行创建自定义函数语句:

create function default.ch_cnv as 'com.my.hive.udf.ChsUDF' using jar 'hdfs:///udf/my_udf.jar';

创建自定义函数报错,提示对应用在CREATE FUNCTION上的DFS_URI对象没有“管理权限”:

Error: Error while compiling statement:FAILED: HiveAccessControlException Permission denied: Principal [name=hive,type=USER] does not have following privileges for operation CREATEFUNCTION [[ADMINPRIVILEGE] on Object [type=DFS_URI, name=hdfs://nameservice1/udf/my_udf.jar]](state=42000,code=40000)

尝试带temporary创建临时函数,也是报同样的错误:

create temporary function default.ch_cnv as'com.my.hive.udf.ChsUDF' using jar 'hdfs:///udf/my_udf.jar';

分析思路:

在SSBA模式下,执行某一些语句会要求对应的HDFS URI必须为rwx+所有者的权限,非常繁琐(所以从Hive 3.0.0开始,基于SSBA的方式进行授权时,对URI权限要求,进行了大幅度的修改。例如建立外表时,不再要求用户必须是HDFS目录的所有者,只需要拥有rw权限即可)。会不会是这里出了问题?

先查阅官方文档:

https://cwiki.apache.org/confluence/display/Hive/SQL+Standard+Based+Hive+Authorization

官方文档上清楚的显示CREATE FUNCTION操作是和HDFS URI权限完全无关的。

Hive在SQL标准权限模式下创建UDF失败的问题排查

难道是官方文档写错了???

尝试将jar权限改为777,所属用户和组都修改为hive。

重试create function语句,没有效果,依然报同样的错误。

这条路走不通,那就试试看能不能从别的信息入手。

重新以hive身份进入beeline,不执行set role admin,就以普通的public角色身份,执行create function语句,提示:

Error: Error while compiling statement:FAILED: HiveAccessControlException Permission denied: Principal [name=hive,type=USER] does not have following privileges for operation CREATEFUNCTION [[ADMINPRIVILEGE] on Object [type=DATABASE, name=default], [ADMIN PRIVILEGE] on Object[type=DFS_URI, name=hdfs://nameservice1/udf/my_udf.jar], [ADMIN PRIVILEGE] onObject [type=FUNCTION, name=default.ch_cnv]](state=42000, code=40000)

这时可以看到,对于执行create function,要求了三个权限:

1、 数据库的admin权限

2、 HDFS URI的admin权限

3、 函数对象的admin权限

其中1和3与官方文档的描述是完全一致的。而我们set role admin之后,1和3都被满足。只有2却依然不满足,这说明并不是我们的管理员角色配置,或是管理员角色切换出现了问题。

那只剩下一种可能性,Hive的这个功能有BUG....

搜索的时候,发现了一名网友遇到了同样的问题:

Hive在SQL标准权限模式下创建UDF失败的问题排查

http://lxw1234.com/archives/2016/01/600.htm

虽然并没有人解答这个问题,但至少说明这并非奇特的个案。

来到Apache的官方JIRA,进行搜索。果然有相关的BUG报告:

Hive在SQL标准权限模式下创建UDF失败的问题排查

https://issues.apache.org/jira/browse/HIVE-11175

从描述和提交的补丁来看,是Hive在SSBA模式下进行create function的语义分析时,错误的将一个输入型资源(UDF的JAR包),当作了输出型资源。要求对该路径施加写的管理员权限(实际应当为要求读的权限),一个已经存在的输入型资源是只读的,于是导致永远卡死在这个验证上。


解决方法:

由于已经对Hive集群实施了SSBA模式,所以我们肯定是不可能为了装载一个UDF函数,就去临时将集群的验证关闭的。彻底关闭会有一段时间暴漏在安全风险中,并且还需要重启服务,临时关闭需要重启一次,开启又要重启一次,这会非常麻烦。

另外一种方式就是去应用前面社区中提交的补丁到源码重新编译,然后替换有问题的JAR包。这个补丁目前还没被集成到Hive的主线中,这么做存在一定风险。而且目前这个集群是客户购买的商业版的CDH,也不太建议自己去弄。

怎么办?这个时候就要请最老旧的Hive CLI上场了!

Hive CLI正是由于不兼容完备的授权模式(Sentry/Ranger/SSBA),可以绕过这些安全限制,所以被官方用beeline给代替了,只在Hive3之前的版本,作为一个兼容性功能保留。

所以一旦开启了Hive授权,都是建议对普通用户禁用Hive CLI的(除非你有Spark多租户的需求,否则都会进行下面的HMS代理禁用)。最常见的禁用手段,就是通过配置Hive的hadoop.proxyuser.hive.groups(Hive Metastore 访问控制和代理用户组覆盖),指定值由 * 改为具体的管理员组,使得普通用户就算进入Hive CLI,也无法操作,但是管理员组用户依然可以进入Hive CLI操作。

所以我们可以使用hive管理员用户,直接进入Hive CLI,绕过SSBA的验证过程,来创建UDF函数:

kinit -k -t hive.keytab hive@XXX.COM

进入Hive CLI后,执行:

create function default.ch_cnv as 'com.my.hive.udf.ChsUDF' using jar 'hdfs:///udf/my_udf.jar';

提示创建成功!

切换到beeline,试用带UDF函数的HQL语句,没有问题。搞定!


↓扫码关注 咕噜咕噜大数据 公众号↓

Hive在SQL标准权限模式下创建UDF失败的问题排查

本文分享自微信公众号 - 咕噜咕噜大数据(gulugulu_bigdata)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4天前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
2年前
HIVE 时间操作函数
日期函数UNIX时间戳转日期函数: from\_unixtime语法:   from\_unixtime(bigint unixtime\, string format\)返回值: string说明: 转化UNIX时间戳(从19700101 00:00:00 UTC到指定时间的秒数)到当前时区的时间格式举例:hive   selec
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
5个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这