[Hive]创建UDF不重启集群解决方案

最近遇到一个问题,上一次没有解决,㝼时间关系没有研究,这次逮着机会了,就回了几个小时研究了一下,现把这个过程整理出来,以备后查

  1. 创建Maven项目,并在pom文件中添加如下的依赖

    
        
            cloudera
            https://repository.cloudera.com/artifactory/cloudera-repos/
        
    
    
    
        
            org.apache.hadoop
            hadoop-common
            2.6.0-cdh5.14.2
        
        
            org.apache.hive
            hive-exec
            1.1.0-cdh5.14.2
        
        
            com.alibaba
            fastjson
            1.2.58
        
        
            org.apache.commons
            commons-lang3
            3.5
        
    
    
    • 版本号需要根据自己的集群版本,其他pom配置就不贴在这里了
    • 我这里用到了FastJson,根据个人需求添加
    • commons-lang3在hive集群的lib里面肯定是有的,但是你的我就不确定了,需要你自己确认,因为后续的步骤中我会有部分操作是合并jar,这个jar不包含commons-lang3
    • 如果是第一次添加可能会耗一定的时间,可能我的网不是很好,等了接近半个小时
  2. 编写自己的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");
        }
        
    }
    
  3. 运行命令打包

    mvn clean package
    
    • 从这里就开始出现问题了,首先我的这个功能依赖于一个fastjson,当然了还有hive对应的lib,lib的jar在集群中肯定是有的,所以这部分jar是没有必要打jar包的,而fastjson是必须打jar的,问题就来了如何解决?这是问题1
    • 问题2是:这个jar怎样运行起来?网上找到一些答案,都是说去配置一个auxlib路径,把所有的jar放在里面,重要的是需要重启集群,但是线上的集群能轻易停吗?显然不可能
  4. 探索之路

    • 在很多的教程中会在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不重启集群解决方案)