python皮同_皮皮调度(3)——Java和Python互相调用的方式

要实现皮皮调度,那么首先遇到的问题就是:Java和Python如何相互调用,并且Java部分能编译成原生程序。

因为皮皮调度在设计之初就有了明确的目标: (参考皮皮调度(1)——从Airflow到DolphinScheduler,以及“皮皮调度”的来历​mp.weixin.qq.com

)Java来实现平台核心框架

Python用来实现各种自定义插件

那让我们来首先列举一下Java和Python互相调用的几种方式

方式1:通过子进程调用Python

这个方式应该是最简单的方式,在Java父进程中,通过ProcessBuilder来启动Python子进程,并重定向子进程的输入输出管道到父进程中。

其优点主要是:相对简单,Java端程序和Python端程序互相隔离,只通过”管道“(pipe)进行通信。

但是其缺点也不少:

首先,Python子进程启动会花费一定时间,这里需要注意,启动python本身是非常快的,但是对于数据处理领域来说,一般python程序都会导入 pandas, numpy等库,而往往 import 这些库就要花费几秒的时间。这就意味着,如果采用子进程调用的方式,那么python中最好做一些较复杂、较耗时的计算,这样才可以使得初始化的几秒的代价显得无足轻重。

而既然”初始化“非常慢,那么,我们自然就会想:是否可以通过多次重用同一个已经完成”冷启动“的子进程来提效呢?

1) 是否可以利用子进程的”输入管道“来不断的发送任务请求,并通过子进程的”输出管道“来接收处理结果。答案是可以的,但是需要注意的是一些细节处理: 比如串行读写管道,比如默认子进程的输出管道是有缓冲的,不一定能及时读取到全部输出。一种比较适合的方式是:父进程分别启动两个单独的线程,一个线程负责发送数据到子进程,另一个线程则专注处理从子进程获取的结果,两个线程之间无需过多进行同步。

2) 子进程也可以使用一些web框架来启动一个HTTP REST服务,这样就不用依赖于比较底层的管道重定向,而是改为REST请求。

但是这些方式都会使得Java和Python之间的通信协议更加复杂。而遵从Unix的设计逻辑,我们最好使得子进程的调用越简单越好: 父进程最好把子进程需要的信息在初始化时就一次性传入(数据小可以直接参数传入,数据大可以通过输入管道传入),然后子进程进行处理并把结果通过管道传给父进程,当任务处理结束,子进程则直接退出。

如何实现这种既架构简单,又初始化快的方式,是值得探索的一个方向。之前曾经想是否可以在Python import完所有module后,把这个时候的程序在内存中的状态存储为一个可执行程序,这样后续的多次运行则避免了每次都重复import的代价,不过目前还没有找到成功的方案。

方式2:GraalVM的多语言混合调用(polyglot)

前文 《GraalVM —— 让Java变得再次强大》 中也提到了GraalVM对于JavaScript和R语言的支持相对还不错,不过对于Python的支持就比较早期(距离能真正使用还有很长的路要走,目前Python基本不可用) (后续文章中我可能也会介绍一下Java 和 Python怎么混合调用)。

GraalVM的远景非常不错,未来有可能能实现更多的语言都在一个进程中无缝集成,不过目前对于Python的支持还非常早期,仍无法使用。

方式3:Jython —— 基于JVM实现的Python平台

Jython项目地址:Jython目前只支持到Python 2.7,对于Python 3.x的支持仍然遥遥无期

Python在数据领域比较火,不光是因为这个语言本身,而更主要的是丰富的生态,这些 CPython的生态无法运行在Jython上,导致Jython无法分到一杯羹

所以,Jython不太适合

方式4:Py4J —— PySpark也在使用的”Java、Python互通桥梁“

Py4J项目地址:

Py4J的特点是:Java和Python分别运行在独立的进程中

首先,需要在Java端启动一个 Gateway Server,并提供一个Java端的Object作为各种功能的入口(Entry Point)

Python端连接Gateway Server,获取到Entry Point对象

接下来Python端就可以从Entry Point切入来远程调用Java端的各种功能, Py4J提供了一系列支持(比如:数据类型序列化、异常处理等),来使得这个”远程调用“的过程方法都仿佛发生在Python中

基于PySpark的广大用户基础,相信Py4J应该是非常稳定的

方式5: Jep —— 基于JNI使得Java无缝调用Python

Jep项目地址:

Jep的好处:Java和Python完全在一个进程中,所需用的资源应该最少

Java和Python的调用就像是函数调用,执行代价很低

PolyNote中使用Jep来使得Notebook的编辑器支持Python代码的快速自动补全,印象非常深刻。

总结

初步看来,要想取得最好的效果,Jep好像是最好的选择,那么我们先来进行Jep的探索之旅吧!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值