【解决方案】UDF内包含资源文件造成OOM的问题。

Viewed 113

OOM问题

如果一个UDF函数内部包含一个几百兆的资源文件。如果UDF入口类和资源文件在一个jar包中时。 会随着并行度,这些资源会被复制多份。 从而导致OOM异常。

解决方案

一:提高JVM堆内存

提高JAVA_OPT Xmx参数, 所有BE的be.conf。
image.png

二:将资源jar包和UDF入口类包分开

思路: 将资源包单独部署, 用其他轻量级的包引用这个资源包。 可以实现资源包在运行时只占用一份内存资源,多个并行度到处引用的效果。
1:先打包文件资源所在的包。此步略......
2:将资源所在包放入{DORIS_HOME}/ be/lib/java_extensions/java-udf文件夹中, 可在BE启动时加载资源文件。
3:创建一个udf入口文件。


import cn.yto.ipplus360.model.Ipv4Basic;
import cn.yto.ipplus360.utils.IpUtils;
public class IpToAddressUDF {
    public String evaluate(String arg) {
  		// 代码逻辑
        // 此处是调用资源文件的核心步骤。
        Ipv4Basic basic = IpUtils.getBasic(ip);
        //代码逻辑
    }
}

4: 编译

-- 将java文件编辑成class文件,同时指定要引用的类路径(即资源所在包.jar)
javac -cp  {DORIS_HOME}/ be/lib/java_extensions/java-udf/资源所在包.jar  上一步的java文件.java

-- 第一步生成的class文件把他打成jar包。 
jar -cvf udf.jar udf.class

-- 生成的java包可作为创建udf函数的入口文件。

5: 创建udf函数

CREATE FUNCTION ipudf(string) RETURNS string PROPERTIES (
"SYMBOL"="入口类名",   -- 因为只有一个java文件, 没有包路径。
"file"="file:/任一文件路径/udf.jar",
"ALWAYS_NULLABLE"="false",
"TYPE"="JAVA_UDF"
);

至此, 该UDF函数创建成功, 且经过测试, 在大数据量下稳定运行。 不会造成OOM。

1 Answers