Hive中UDFJar包被加载的时机

需求

需要编写一个UDF,每次在脚本执行的时候,UDF去加载HDFS上的指定目录的文件的内容。

实现

通过静态代码块去执行加载HDFS上文件的内容的操作。

伪代码如下

HashMap<String,String> dangerMap = new HashMap<>();

static {
  // 配置集群namenode主备信息
  // 读取信息
  // 循环遍历放入map中
}

public Object evaluate(String args) throws HiveException {
   // 使用dangerMap执行具体的业务
   // ......       
}

想到的问题

1、这个UDF对应的jar包是什么时候加载的?
2、会不会造成重复读取的问题?

针对问题进行的测试

测试版本

JDK1.8
Hive 3.1.2
Hadoop 3.1.3

测试代码

通过创建一个int的静态变量做累加,和一个时间静态变量进行

public class Test extends GenericUDF {
    static int i = 0;

    static Timestamp ts = null;

    static {
        i++;
        ts = new Timestamp(System.currentTimeMillis());
    }



    @Override
    public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
        if(arguments.length!=1){
            throw new UDFArgumentException("参数个数不为1");
        }
        // 设置返回值类型
        return PrimitiveObjectInspectorFactory.javaStringObjectInspector;
    }

    @Override
    public Object evaluate(DeferredObject[] arguments) throws HiveException {
        //String s = arguments[0].get().toString();
        int j = i;
        return ts + "当前值+ " + j;
    }

    @Override
    public String getDisplayString(String[] children) {
        return "";
    }

    public static void main(String[] args) throws HiveException {
        Test test = new Test();
        Object evaluate = test.evaluate(null);
        System.out.println(evaluate);


    }

}

测试过程

临时函数

使用临时函数去操作执行add jar操作

第一次进入Hive后执行。
Hive中UDFJar包被加载的时机_第1张图片
退出当前回话,在进入Hive后执行。
Hive中UDFJar包被加载的时机_第2张图片

结论

每一次调用注册临时函数的方法都会加载jar包。

永久函数

第一次进入hive注册永久函数
Hive中UDFJar包被加载的时机_第3张图片

退出后,第二次进行hive使用udf函数。
并打印当前时间。
Hive中UDFJar包被加载的时机_第4张图片

结论

每次回话中,首次调用注册的永久函数,会加载jar包,执行static代码块的内容。

结论

hive在add jar的时候会把udf类加载进来,而根据JVM类加载机制,当对类进行加载的时候会执行static代码块的内容。

所以:
只要保证是当前会话下,无论使用永久函数还是临时函数,都可以通过静态代码块去对数据完成提前加载,并且不会造成重复加载的问题。

其他问题

可以考虑使用UDF函数生命周期的initialize,该方法待测试。

你可能感兴趣的:(大数据,hive,hadoop,大数据)