如何让UDF的class只加载一次

StarRocks的UDF class 每次执行都会重新加载,这样会让UDF中的静态变量比较安全,不会互相影响。但是一些特殊的场景需要让UDF只加载一次。本文将描述如何让UDF只加载一次。

假设我们原始的class是 LoadTest.java

public class LoadTest {
    static {
        System.out.println("load UDF");
    }
    public String evaluate(String a, Integer b) {
        return a + b;
    }
}

我们需要为他额外编写一个包装壳,在里面调用我们想调用的逻辑

public class Caller {
    static {
        System.out.println("load Caller");
    }
    public String evaluate(String a, Integer b) {
        return new LoadTest().evaluate(a, b);
    }
}

我们把 Caller 和 LoadTest 分别打一个包

javac ./*.java
jar -cf ./caller.jar ./Caller.class
jar -cf ./load_test.jar ./LoadTest.class

我们把LoadTest打的包放到 be/lib/hadoop/common/lib/

mv ./load_test.jar $STARROCKS_HOME/be/lib/hadoop/common/lib/

然后把caller这个函数注册到FE

create function Caller (string, int) returns string properties(
    "symbol" = "Caller", 
    "type" = "StarrocksJar",
    "file"="http://127.0.0.1:8084/caller.jar"
);
mysql> select caller(1,2);
+--------------+
| caller(1, 2) |
+--------------+
| 12           |
+--------------+
1 row in set (1.23 sec)

执行多次我们可以看到 LoadTest 只会被加载一次

load Caller
load UDF
load Caller
load Caller
load Caller
1赞

请问如果是udaf 应该怎么写 试了一下 没有成功 :smiley:

udaf也是适用的 怎么写的呢 麻烦提供下对应语句

LoadTest 要怎么做动态更新呢,我更新了Jar包到 $STARROCKS_HOME/be/lib/hadoop/common/lib/ 发现 caller 还是引用到旧包

3.1+ 创建UDF的时候可以加个 isolation 属性

CREATE FUNCTION test_shared(string)  
RETURNS string properties  ( 
"symbol" = "SharedUDF",
"type" = "StarrocksJar", 
"file" = "http://XXXXX/create_file.jar",
"isolation"="shared"
);

我在starrocks 3.1.11使用了这种方式,但是在调用时发现找不到方法
SQL 错误 [1064] [42000]: java.lang.NoSuchMethodError: com.xxxxx.utils.TableInitFromStarRocks.evaluate(Ljava/lang/String;Ljava/lang/Integer;)Ljava/lang/String;[com.xxxxx.starrocks.udf.FuncGetChannelNew.evaluate(FuncGetChannelNew.java:18), com.starrocks.udf.gen.CallStub.batchCallV(Unknown Source)]