Flink加载自定义Jar包

本文介绍了如何在Flink中使用FlinkSQ构建实时计算任务时动态加载自定义UDF,通过pipeline.classpaths配置和URLClassLoader加载Jar包,以及如何在HDFS高可用场景下获取active节点的HTTP路径。期待Flink未来提供更便捷的RESTAPI接口来管理用户自定义Jar包。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

用户只需要编写Fink SQ就可以快速构建实时计算任务,通过yarn session模式试运行或者语法校验需要自定义udf,其中用户可以通过上传Jar包的方式支持自定义函数UDF,这里就需要在启动作业的时候能够动态加载自定义Jar包。

解决

Flink 官方文档可以招待找到关于 pipeline.classpath 参数配置的描述,通过该配置项来加载classpath。yarn的api并没有提供该配置项目的参数入口,所以在作业的 main 函数中直接通过反射获取 Configuration 对象,并且直接设置 pipeline.classpaths 的值。

private static void loadPipelineClassPaths(StreamExecutionEnvironment env, List<String> jarList) throws Exception{
        Field configuration = StreamExecutionEnvironment.class.getDeclaredField("configuration");
        configuration.setAccessible(true);
        Configuration o = (Configuration)configuration.get(env);
 
        Field confData = Configuration.class.getDeclaredField("confData");
        confData.setAccessible(true);
        Map<String,Object> temp = (Map<String,Object>)confData.get(o);
        temp.put("pipeline.classpaths", jarList);
 }

同时还需要在作业的 main 方法里动态加载Jar包到 URLClassloader里:

public static void loadJar(URL jarUrl) {
        //从URLClassLoader类加载器中获取类的addURL方法
        Method method = null;
        try {
            method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
        } catch (NoSuchMethodException | SecurityException e1) {
            e1.printStackTrace();
        }
        assert method != null;
        boolean accessible = method.isAccessible();
        try {
            if (!accessible) {
                method.setAccessible(true);
            }
            URLClassLoader classLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
            method.invoke(classLoader, jarUrl);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            method.setAccessible(accessible);
        }
  }

-C参数使用的类加载进行加载与user jar是一个类加载器,taskManager运行的时候会加载并且相应的job停止时自动卸载,同时每个job都会有自己的ClassLoader实现相互隔离。希望Flink 后续版能够在Rest API 层面能够直接提供参数来加载用户自定义的Jar包,并且能够直接读取HDFS文件来加载Jar包。

暂时将用户自定义的Jar包上传到hdfs并获取到hdfs的http连接地址,形式如下:
http://hadoop1:50070/webhdfs/v1/test.jar?op=OPEN&namenoderpcaddress=nnCluster&offset=0
对hdfs高可用场景,可以通过如下方式获取到active节点连接地址:

public static String getActiveHttpPath(Hdfs hdfsCon) throws IOException {
        HdfsFileSystem hdfsFileSystem = SpringUtils.getBean(HdfsFileSystem.class);
        InetSocketAddress active = HAUtil.getAddressOfActive(hdfsFileSystem.getHdfs(hdfsCon));
        String httpPath = "http://" + active.getAddress().getHostAddress() + ":50075/webhdfs/v1";
        return httpPath;
 }

Docker Compose是一种配置文件格式,用于定义和管理一组相关的Docker容器服务,通常与Fluentd、Kubernetes等一起使用。如果你想通过Docker Compose部署Apache Flink并上传自定义JAR,你可以按照以下步骤操作: 1. **创建`docker-compose.yml`文件**: 首先,你需要在项目的根目录下创建一个`docker-compose.yml`文件,定义Flink的镜像、网络和其他必要配置。例如,你可以设置一个Flink Worker服务,并指定使用本地的JAR: ```yaml version: '3' services: flink: image: flink:latest volumes: - ./my-jar.jar:/opt/flink/lib/my-jar.jar command: ["start", "--configDir", "/path/to/config"] ``` 这里假设`my-jar.jar`是你的自定义JAR,路径需替换实际位置。 2. **打JAR**: 将你的Java应用代码编译成JAR,如果还没有做,可以使用`mvn package` (Maven) 或 `gradle jar` (Gradle)命令。 3. **启动集群**: 打开终端,在含`docker-compose.yml`的目录下运行: ``` docker-compose up -d ``` `-d` 参数表示后台启动,服务会作为守护进程运行。 4. **提交JAR到容器**: 如果需要在运行时添加新JAR,你可以使用`docker exec`命令,如: ```bash docker exec -it flink bash cp /path/to/new-jar.jar /opt/flink/lib/ ``` 然后退出容器,更改会立即生效。 5. **配置作业**: 要运行含有自定义JAR的任务,你需要在Flink配置中引用这个JAR,这通常在`conf/taskmanager-resources.yml`或`conf/local.properties`文件中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风卷残尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值