[Hive]创建UDF不重启集群解决方案
2019-07-26 本文已影响0人
帅可儿妞
最近遇到一个问题,上一次没有解决,㝼时间关系没有研究,这次逮着机会了,就回了几个小时研究了一下,现把这个过程整理出来,以备后查
-
创建Maven项目,并在pom文件中添加如下的依赖
<repositories> <repository> <id>cloudera</id> <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url> </repository> </repositories> <dependencies> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>2.6.0-cdh5.14.2</version> </dependency> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-exec</artifactId> <version>1.1.0-cdh5.14.2</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.58</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.5</version> </dependency> </dependencies>
- 版本号需要根据自己的集群版本,其他pom配置就不贴在这里了
- 我这里用到了FastJson,根据个人需求添加
- commons-lang3在hive集群的lib里面肯定是有的,但是你的我就不确定了,需要你自己确认,因为后续的步骤中我会有部分操作是合并jar,这个jar不包含commons-lang3
- 如果是第一次添加可能会耗一定的时间,可能我的网不是很好,等了接近半个小时
-
编写自己的UDF,我的如下:
package com.xxx.bigdata.etl.hive.udf; import com.alibaba.fastjson.JSONObject; import org.apache.commons.lang3.StringUtils; import org.apache.hadoop.hive.ql.exec.UDF; /** * @author ShrekerNil */ public class FieldPlatformHandlerUDF extends UDF { public String evaluate(String content) { JSONObject json = (JSONObject) JSONObject.parse(content); if (json == null) return null; String platFrom = json.getString("platFrom"); if (StringUtils.isNotBlank(platFrom)) { return platFrom; } return json.getString("platform"); } }
-
运行命令打包
mvn clean package
- 从这里就开始出现问题了,首先我的这个功能依赖于一个
fastjson
,当然了还有hive对应的lib,lib的jar在集群中肯定是有的,所以这部分jar是没有必要打jar包的,而fastjson是必须打jar的,问题就来了如何解决?这是问题1 - 问题2是:这个jar怎样运行起来?网上找到一些答案,都是说去配置一个auxlib路径,把所有的jar放在里面,重要的是需要重启集群,但是线上的集群能轻易停吗?显然不可能
- 从这里就开始出现问题了,首先我的这个功能依赖于一个
-
探索之路
- 在很多的教程中会在hive cli中使用 add jar命令来添加jar,而且我试过了,我的方法通过如下,但是确定是:只能在本次会话找那个有效,重开窗口就没有了,甚是肉疼:
hive(dev)>add jar /tmp/fastjson-1.2.58.jar hive(dev)>add jar /tmp/etl_hive-0.0.1.jar; hive(dev)>CREATE TEMPORARY FUNCTION handle_platform as 'com.xxx.bigdata.etl.hive.udf.FieldPlatformHandlerUDF';
- 接着找到了一个创建永久function的方法
create function handle_platform as 'com.xxx.bigdata.etl.hive.udf.FieldPlatformHandlerUDF' using jar 'hdfs:///hive/prd/lib/hive-udf-0.0.1.jar';
- 需要注意的是:这里有个小坑,原理不是很明白,就是协议后面不要跟ip:port,当然了需要在metastore主机上执行,他会自动查找的,因为hive的配置中肯定有连接metastore的配置
- 还有一个前提是,你需要把jar上传到对应的HDFS目录
- 问题又来了,这个jar中只有UDF,而没有JSONObject,于是网上各种搜:
java 删除jar中部分文件
。。。- 经过一系列的摸索,终于找到了办法,就是直接把hive-udf-0.0.1.jar和jsonobject的jar合并即可,于是写了个脚本,在package操作完成后执行:
#/bin/sh cp /Users/shrekernil/Documents/GitRepo/GitLab/etl_hive/target/hive-udf-0.0.1.jar ~/Desktop/jar_merge/ cp /Users/shrekernil/.m2/repository/com/alibaba/fastjson/1.2.58/fastjson-1.2.58.jar ~/Desktop/jar_merge/ cd ~/Desktop/jar_merge/ jar -xvf hive-udf-0.0.1.jar jar -xvf fastjson-1.2.58.jar rm -f ./*.jar jar -cvfM hive-udf-0.0.1.jar ./
- 这样,合并的jar上传到HDFS上,然后执行上传创建永久UDF的方法就成功了
- 经过一系列的摸索,终于找到了办法,就是直接把hive-udf-0.0.1.jar和jsonobject的jar合并即可,于是写了个脚本,在package操作完成后执行:
- 在很多的教程中会在hive cli中使用 add jar命令来添加jar,而且我试过了,我的方法通过如下,但是确定是:只能在本次会话找那个有效,重开窗口就没有了,甚是肉疼: