Java JNI在flink纱线簇作业中的应用
我有一个应用程序,它通过Java JNI在flink纱线簇作业中的应用,java,scala,hadoop,apache-flink,Java,Scala,Hadoop,Apache Flink,我有一个应用程序,它通过RemoteExecutionEnvironmentscala API将Apache Flink作业分派到AWS Elastic MapReduce纱线集群 这些作业使用JNI通过C库运行部分计算。在开发过程中,我只是在RichCrossFunction的open()方法中加入了一个System.loadLibrary()调用来加载这个JNI库。这在LocalExecutionEnvironment中运行良好 现在,我要迁移到RemoteExecutionEnvironm
RemoteExecutionEnvironment
scala API将Apache Flink作业分派到AWS Elastic MapReduce纱线集群
这些作业使用JNI通过C库运行部分计算。在开发过程中,我只是在RichCrossFunction
的open()
方法中加入了一个System.loadLibrary()
调用来加载这个JNI库。这在LocalExecutionEnvironment
中运行良好
现在,我要迁移到RemoteExecutionEnvironment
,这似乎不再有效。看起来Flink每次分派作业时都在使用一个新的类加载器
,而我在计算节点上的另一个类加载器中已经加载了本机库
一些Google告诉我,这是Tomcat应用程序的一个常见问题,Tomcat常见问题解答中提供了一个解决方案:
火石或纱线是否有类似的解决方案
此外,是否可以避免每次作业排队时都重新提交JAR?我总是在这个集群上使用同一个jar,因此这是不必要的开销…我通过在JNI jar中的静态初始值设定项中调用loadLibrary
来解决这个问题,然后将JNI jar放在Flink的/lib
文件夹中,类似于上面Tomcat链接中的模式
它通过warn session.sh
启动过程自动复制到Flink TaskManager。这使我能够像对待Tomcat一样,绕过类加载器隔离
我使用的是Maven,所以我使用Maven shade插件阻止JNI jar包含在我的uberjar中
我仍然不知道这是否是最好的方法,因为flink手册不鼓励使用/lib
文件夹,因为它不尊重他们的ClassLoader管理(),但这正是我想要的
也许另一种方法是使用NativeLoader模式,为每个类加载器创建一个单独的临时文件,但这会创建一堆重复的本机库,这种方法对我来说很有效