Flink动态添加依赖Jar包提交到Yarn

背景

开发的flink程序,要使用yarn-cluster的方式进行部署。

程序中依赖了很多第三方jar包,不想用shade那种打包方式打成一个大jar包,然后提交。

想将应用程序jar包和依赖jar包分开,依赖的jar包在提交时一起提交上去(像spark on yarn直接指定“–jars”这样),但是找了好久发现flink官方没有提供这样的方式。

直接将依赖的jar包放在flink的lib目录下,可以实现,但是感觉这样会污染flink的lib包。

于是找到了如下方法,可以实现类似的功能。在此记录分享一下。

大概实现就是修改flink提交的脚本,开放了用户添加自己的jar依赖能力,然后在提交时指定依赖的jar包目录。

过程

  1. 下载flink源码包

    下载自己flink对应的版本的源码包。以下是源码包地址:

    https://mirrors.tuna.tsinghua.edu.cn/apache/flink/

    https://archive.apache.org/dist/flink/

  2. 修改flink-yarn模块下的YarnClusterDescriptor 类的addLibFoldersToShipFiles 方法,在方法首部添加如下代码:

    USER_LIB_DIR就是我们之后要用到的环境参数

    String userLibDir = System.getenv().get("USER_LIB_DIR");
    if (userLibDir != null) {
       File directoryFile = new File(userLibDir);
       if (directoryFile.isDirectory()) {
          effectiveShipFiles.add(directoryFile);
       } 
    }
    
  3. 编译flink-yarn模块。执行如下命令编译

    mvn clean package -DskipTests -Dfast
    
  4. 用编译后得到的YarnClusterDescriptor.class替换flink的lib目录中flink-dist.jar对应的类

    # 查看YarnClusterDescriptor.class在jar包中的目录路径
    jar tvf flink-dist_2.11-1.11.3.jar|grep YarnClusterDescriptor.class
    # 目录路径如下
    58667 Fri Feb 05 20:28:38 CST 2021 org/apache/flink/yarn/YarnClusterDescriptor.class
    
    
    # 创建对应的目录,并将编译后的YarnClusterDescriptor.class放进去
    mkdir -p org/apache/flink/yarn
    mv YarnClusterDescriptor.class org/apache/flink/yarn
    
    # 将Class文件更新回jar包里面
    jar uvf flink-dist_2.11-1.11.3.jar org/apache/flink/yarn/YarnClusterDescriptor.class
    
    
    
  5. 修改flink安装目录下bin下的config.sh文件,在constructFlinkClassPath函数中添加如下代码:

        for f in $USER_LIB_DIR/*.jar
        do
        FLINK_CLASSPATH=$FLINK_CLASSPATH:$f
        done
        
    
    ----------------------------添加后的----------------------------
    constructFlinkClassPath() {
    
        local FLINK_DIST
        local FLINK_CLASSPATH
       
        for f in $USER_LIB_DIR/*.jar
        do
        FLINK_CLASSPATH=$FLINK_CLASSPATH:$f
        done
    
        while read -d '' -r jarfile ; do
            if [[ "$jarfile" =~ .*/flink-dist[^/]*.jar$ ]]; then
                FLINK_DIST="$FLINK_DIST":"$jarfile"
            elif [[ "$FLINK_CLASSPATH" == "" ]]; then
                FLINK_CLASSPATH="$jarfile";
            else
                FLINK_CLASSPATH="$FLINK_CLASSPATH":"$jarfile"
            fi
        done < <(find "$FLINK_LIB_DIR" ! -type d -name '*.jar' -print0 | sort -z)
    
        if [[ "$FLINK_DIST" == "" ]]; then
            # write error message to stderr since stdout is stored as the classpath
            (>&2 echo "[ERROR] Flink distribution jar not found in $FLINK_LIB_DIR.")
    
            # exit function with empty classpath to force process failure
            exit 1
        fi
    
        echo "$FLINK_CLASSPATH""$FLINK_DIST"
    }
    
    
  6. 修改应用的启动脚本,在我们启动脚本前设置用户lib库,如下:

    export USER_LIB_DIR=/xxx/lib
    
  7. 将自己的jar依赖放到lib下。

  8. 执行应用程序的启动脚本就可以将我们自己的依赖也一起提交上去了。

参考

flink 动态支持依赖jar包提交http://www.manongjc.com/detail/19-dezdtwgjprkbblt.html

清华镜像站https://mirrors.tuna.tsinghua.edu.cn/apache/flink/

apache镜像站https://archive.apache.org/dist/flink/

你可能感兴趣的:(Flink,flink,flink添加依赖,flink,yarn)