作者:余枫
1
问题重现
1.RedHat7.2
2.CDH6.2.0
3.使用root进行操作
Hive的TRANSFORM关键字提供了在SQL中调用自写脚本的功能。在不想写Hive UDF的情况下,可以通过使用Python脚本来实现UDF功能。
在Hive中使用Python脚本处理数据时可以通过add file的方式添加脚本文件,在未启用Sentry时add file命令正常执行,但在集群启用Sentry后使用add file命令添加Python脚本时报错"Error: Insufficient privileges to execute add(state=42000, code=0)",如下图所示:
2
问题分析
在查询官方资料后了解到,在Hive启用Sentry后,ADD FILE/JAR命令被加入了黑名单,已经无法使用了。参考地址:
https://www.cloudera.com/documentation/enterprise/5-12-x/topics/cdh_sg_sentry.html
如果要继续在Hive中使用TRANSFORM执行Python脚本,只能使用官方推荐的其他方式。
3
问题解决
在启用Sentry的情况下,想要使用TRANSFORM执行Python脚本,针对这种情况可以通过如下两种方式实现,
3.1
解决方式一
在使用TRANSFORM时添加上Python的全路径以及脚本的全路径,并且保证集群的每个节点上都有Python环境且访问路径相同,Python脚本也必须在每个节点上都存在。
1.查看每个节点上的Python环境和脚本
2.在Hive中进行查询
SELECT TRANSFORM (userid, movieid, rating, unixtime) USING '/usr/bin/python /tmp/test.py' AS (userid, movieid, rating, weekday) FROM u_data;
Python脚本中的逻辑是将unixtime这个时间戳转换为对应那天是星期几。
查询表原始数据:
执行TRANSFORM后的结果:
可以看出这种方式能够正常使用Python脚本,但是这种方式略显繁琐,需要每个数据节点上都有这个Python脚本文件,下面介绍另一种方式。
3.2
解决方式二
将Python脚本上传到HDFS,使所有数据节点都能够访问到脚本文件,需要在Hive中使用时,用Sentry将该脚本文件在HDFS上的URI授权给对应的角色。
1.在Python脚本文件的第一行添加一行代码
#!/usr/bin/env python
2.将脚本上传到HDFS
hadoop fs -put /tmp/test.py /hive/lib
3. 使用Sentry将URI授权给角色admin(根据实际情况授予角色)
GRANT ALL ON URI 'hdfs://cdh177.fayson.com:8020/hive/lib/test.py' TO ROLE admin;
4.在Hive中查询
SELECT TRANSFORM (userid, movieid, rating, unixtime) USING 'hdfs://cdh177.fayson.com:8020/hive/lib/test.py' AS (userid, movieid, rating, weekday) FROM u_data;
这种方式不再需要每个数据节点的相同路径下都有同一个Python脚本文件,而是将脚本上传到HDFS上,让所有数据节点都能够访问,再通过Sentry授权在Hive中进行使用。
在上面两种方式中,Python脚本每次都读取了一整行数据,如果说只针对要处理的那个字段,那么需要对脚本进行修改即可实现。
1.修改脚本
2.将脚本上传到HDFS
3.在Hive中对一个字段进行TRANSFORM
SELECT TRANSFORM (unixtime) USING 'hdfs://cdh177.fayson.com:8020/hive/lib/test.py' AS weekday FROM u_data;
4
补充测试
在上一节介绍完两种方式后,这一节来介绍一下如何在未启用Sentry的集群的Hive中使用Python脚本。
1.在Python脚本第一行加入一行代码
#!/usr/bin/env python
2.修改脚本的权限
chmod 777 /tmp/test.py
3.在Hive中使用ADD FILE将文件添加到分布式缓存
ADD FILE /tmp/test.py;
4.查询
SELECT TRANSFORM (userid, movieid, rating, unixtime) USING '/tmp/test.py' AS (userid, movieid, rating, weekday) FROM u_data;
5
总结
1.在集群启用了Sentry后,因为处于安全原因,ADD FILE/JAR命令被加入到黑名单无法执行,只能使用文档中介绍的方式进行配置。
2.解决方法一在每个节点都需要有同样路径的Python脚本,实际使用中该方式较为繁琐;
3.解决方法二是将脚本文件上传到HDFS上,让数据节点都能够访问,这样的方式优于方式一。
4.TRANSFORM支持单个字段或多个字段方式,如果传入多个字段在处理时需要通过split方式将字段拆分。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有