需要编写一个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后执行。
每一次调用注册临时函数的方法都会加载jar包。
第一次进入hive注册永久函数
退出后,第二次进行hive使用udf函数。
并打印当前时间。
每次回话中,首次调用注册的永久函数,会加载jar包,执行static代码块的内容。
hive在add jar的时候会把udf类加载进来,而根据JVM类加载机制
,当对类进行加载的时候会执行static代码块的内容。
所以:
只要保证是当前会话下,无论使用永久函数还是临时函数,都可以通过静态代码块去对数据完成提前加载,并且不会造成重复加载的问题。
可以考虑使用UDF函数生命周期的initialize
,该方法待测试。