简介
Python API 提供了多种不同的运行时执行模式,您可以根据用例需求和作业特点选择合适的模式。这些执行模式定义了如何运行 Python 用户定义的函数。
在版本 1.15 之前,只存在一种执行模式,被称为“PROCESS 执行模式”。在这个模式中,Python 用户定义的函数会在单独的 Python 进程中运行。
然而,在版本 1.15 中,引入了一种全新的执行模式,被称为“THREAD 执行模式”。在 THREAD 模式中,Python 用户定义的函数会在 JVM 内执行。
请注意:在同一个 JVM 中运行的多个 Python 用户定义函数仍然会受到全局解释器锁 (GIL) 的限制。
何时选择 THREAD 执行模式?
引入 THREAD 模式的目的是为了克服 PROCESS 模式中涉及进程间通信所带来的序列化/反序列化和网络通信开销。因此,如果性能不是您的主要关注点,或者您的 Python 用户定义函数本身就是作业性能的瓶颈,那么 PROCESS 模式将是最佳选择。与 THREAD 模式相比,PROCESS 模式提供了更好的隔离性。
配置 Python 执行模式
您可以通过设置 python.execution-mode
属性来配置执行模式。有两种可能的取值:
PROCESS
:Python 用户定义函数将在单独的 Python 进程中执行(默认)。THREAD
:Python 用户定义函数将在 JVM 中执行。
您可以按照以下方式在 Python Table API 或 Python DataStream API 作业中指定执行模式:
Python Table API
# 设置为 `PROCESS` 模式
table_env.get_config().set("python.execution-mode", "process")
# 设置为 `THREAD` 模式
table_env.get_config().set("python.execution-mode", "thread")
Python DataStream API
config = Configuration()
# 设置为 `PROCESS` 模式
config.set_string("python.execution-mode", "process")
# 设置为 `THREAD` 模式
config.set_string("python.execution-mode", "thread")
# 创建 StreamExecutionEnvironment 执行环境
env = StreamExecutionEnvironment.get_execution_environment(config)
支持的用例
Python Table API
以下表格展示了 Python Table API 中 THREAD 执行模式的支持情况:
UDF 类型 | PROCESS 支持 | THREAD 支持 |
---|---|---|
Python UDF | 支持 | 支持 |
Python UDTF | 支持 | 支持 |
Python UDAF | 支持 | 不支持 |
Pandas UDF & Pandas UDAF | 支持 | 不支持 |
Python DataStream API
以下表格展示了 Python DataStream API 中 PROCESS
执行模式和 THREAD
执行模式的支持情况:
操作类型 | PROCESS 支持 | THREAD 支持 |
---|---|---|
Map | 支持 | 支持 |
FlatMap | 支持 | 支持 |
Filter | 支持 | 支持 |
Reduce | 支持 | 支持 |
Union | 支持 | 支持 |
Connect | 支持 | 支持 |
CoMap | 支持 | 支持 |
CoFlatMap | 支持 | 支持 |
Process Function | 支持 | 支持 |
Window Apply | 支持 | 支持 |
… | … | … |
目前,在所有情况下,使用 THREAD 执行模式执行 Python UDF 仍然不完全支持。在这些情况下,将回退到 PROCESS 执行模式。因此,即使配置作业为 THREAD 模式执行,实际上也可能以 PROCESS 模式执行。
THREAD
执行模式仅支持 Python 3.7+ 版本。
执行行为
本节将概述 THREAD 执行模式的执行行为,并与 PROCESS 执行模式进行对比。
PROCESS 执行模式
在 PROCESS 执行模式下,Python 用户定义函数会在独立的 Python Worker 进程中运行。Java 运算符进程通过多种 Grpc 服务与 Python Worker 进行通信。
THREAD 执行模式
在 THREAD 执行模式下,Python 用户定义函数会与 Java 运算符在同一个进程中运行。PyFlink 使用第三方库 PEMJA 在 Java 应用程序中嵌入 Python。
以下是两者的主要区别:
-
在 THREAD 模式下,Python 函数直接在 JVM 线程上运行,避免了进程间通信的开销。然而,多个函数之间会失去进程隔离性。
-
在 THREAD 模式下,函数代码不能执行一些只在进程内部安全的操作,比如创建新进程等。
-
THREAD 模式下不支持 Pandas UDF,因为 Pandas 自身的 GIL 与 JVM 的并发存在冲突。
-
在 THREAD 模式下,异常堆栈跟踪更加友好,可以直接打印 Java/Python 混合调用的栈信息。
-
在 THREAD 模式下,函数的执行时长可以直接通过 JVM 进行监控。而在 PROCESS 模式下,需要通过独立的服务来实现。
总而言之,THREAD 模式更轻量级,而 PROCESS 模式更加安全隔离。
PyFlink 详细资料关注公众号