PyFlink TableEnvironment 创建方式、核心 API、作业执行、UDF 与依赖、Catalog 管理与容错配置

1. TableEnvironment 是什么,解决什么问题

Flink 的 Table/SQL 是声明式 API,你写的 DDL、SQL、Table API 链式调用,本质上都是在描述"要什么",由 Flink Planner 生成执行计划并提交作业执行。

TableEnvironment 的职责可以理解为三件事:

  • 定义与管理元数据:临时表/视图、Catalog 表/视图、函数、模块
  • 构建与解释计划:sql_query/explain_sql、Table.explain、StatementSet.explain
  • 触发执行与作业配置:execute_sql(DML)、StatementSet.execute、Table.execute_insert,配置并行度/容错等

2. 创建 TableEnvironment 的两种常用方式

2.1 推荐方式:EnvironmentSettings 创建(更纯粹的 Table/SQL 程序)

适用于:主要用 Table API / SQL,不强依赖 DataStream API。

python 复制代码
from pyflink.common import Configuration
from pyflink.table import EnvironmentSettings, TableEnvironment

config = Configuration()
config.set_string('execution.buffer-timeout', '1 min')

env_settings = (
    EnvironmentSettings.new_instance()
    .in_streaming_mode()
    .with_configuration(config)
    .build()
)

table_env = TableEnvironment.create(env_settings)

要点:

  • in_streaming_mode() 常用于流作业;你也可以按需要选择 batch 模式
  • with_configuration(config) 可以把一些执行参数提前塞进去(例如 buffer-timeout)

2.2 与 DataStream 互操作:StreamTableEnvironment(需要 DataStream 能力时)

适用于:你想在同一条链路里混用 DataStream 与 Table/SQL(例如自定义 Source、复杂 ProcessFunction、Table 负责聚合与 Join)。

python 复制代码
from pyflink.datastream import StreamExecutionEnvironment
from pyflink.table import StreamTableEnvironment

env = StreamExecutionEnvironment.get_execution_environment()
table_env = StreamTableEnvironment.create(env)

经验建议:

  • 如果你不需要 DataStream 侧能力,就用纯 TableEnvironment,更简单
  • 如果你要用 DataStream 的 source/sink 或算子,就用 StreamTableEnvironment

3. Table/SQL 操作:建表、视图、查询与执行(最常用 API)

这一组 API 就是日常"写作业"的主流程。

3.1 从 Python 数据构造 Table:from_elements / from_pandas

快速构造测试数据、单元测试、demo 都很好用。

  • from_elements(elements, schema=None, verify_schema=True)
  • from_pandas(pdf, schema=None, split_num=1)

例子:

python 复制代码
table = table_env.from_elements([(1, 'Hi'), (2, 'Hello')], ['id', 'data'])

3.2 取出已注册对象:from_path

from_path(path) 用来把 Catalog/临时对象转成 Table:

python 复制代码
t = table_env.from_path("sql_source")

它也是替代旧 API scan() 的推荐写法。

3.3 注册与管理视图:create_temporary_view / create_view

  • create_temporary_view(view_path, table):临时视图(会话级)
  • create_view(view_path, table, ignore_if_exists=False):持久视图(取决于 Catalog 是否持久化)

典型用法:把 Table API 产物暴露给 SQL 使用。

python 复制代码
table_env.create_temporary_view("table_api_table", table)
table_env.execute_sql("INSERT INTO sink SELECT * FROM table_api_table")

3.4 注册与管理表:create_temporary_table / create_table

两类对象别混:

  • Temporary Table:临时表(常用于 source/sink,作业脚本里即建即用)
  • Catalog Table:持久化表(通常配合 HiveCatalog、JDBC Catalog 等)

3.5 execute_sql 与 sql_query:一个"执行",一个"拿 Table"

  • execute_sql(stmt):执行单条语句(DDL/DML/DQL/SHOW/DESCRIBE/EXPLAIN/USE)
  • sql_query(query):把 SQL 查询结果转成 Table(用于继续 Table API 链式处理)

示例:

python 复制代码
t = table_env.sql_query("SELECT id, SUM(v) AS s FROM T GROUP BY id")

关于 DML 的一个关键点:

  • execute_sql("INSERT INTO ...") 通常是异步提交(远端集群场景更符合预期)
  • 本地 mini cluster / IDE 调试时经常需要 .wait() 等待结束

4. 作业执行与解释计划:explain_sql / StatementSet / 多 Sink

4.1 explain_sql:快速看 SQL 的 AST 与执行计划

当你想确认优化有没有生效(谓词下推、投影裁剪、Join 策略等),优先用:

python 复制代码
plan = table_env.explain_sql("SELECT ...")
print(plan)

4.2 StatementSet:一次作业写多个 Sink(生产很常用)

你有多个下游(例如同时写 Kafka、ES、Blackhole/Print Debug),别拆多个作业,用 StatementSet:

python 复制代码
statement_set = table_env.create_statement_set()
statement_set.add_insert_sql("INSERT INTO sink1 SELECT ...")
statement_set.add_insert_sql("INSERT INTO sink2 SELECT ...")
statement_set.execute().wait()

优点:

  • 复用同一份 source 与计算链路
  • 只提交一个 job,运维更简单

4.3 废弃 API 迁移建议(少走弯路)

这些在新代码里建议不要再用:

旧 API 推荐替代
scan from_path
register_table create_temporary_view
sql_update execute_sql
explain(table=...) explain_sql / Table.explain / StatementSet.explain
execute(job_name) execute_sql / StatementSet.execute / Table.execute_insert

5. UDF 管理:Python/Java 函数注册与优先级

TableEnvironment 可以直接注册函数,也可以用 SQL 注册(CREATE FUNCTION)。

常用接口:

  • create_temporary_function(path, function):临时 Catalog 函数
  • create_temporary_system_function(name, function):临时 System 函数
  • create_java_function(path, function_class_name, ...):注册 Java 函数到 Catalog
  • create_java_temporary_function(...) / create_java_temporary_system_function(...)

一个实用规则:

  • 临时 system function 如果和 临时 catalog function 同名,system 的优先级更高(更"全局")。

删除相关:

  • drop_function
  • drop_temporary_function
  • drop_temporary_system_function

6. Python 依赖管理:让 UDF 在集群里也能找到你的包

很多 PyFlink 作业跑在集群时失败,不是逻辑错,而是 UDF worker 找不到依赖。

TableEnvironment 提供了三套常用方式:

6.1 add_python_file:加单个文件/包/目录到 PYTHONPATH

python 复制代码
table_env.add_python_file("/path/to/my_udfs.py")

6.2 set_python_requirements:用 requirements.txt 安装三方依赖

python 复制代码
table_env.set_python_requirements(
    requirements_file_path="/path/requirements.txt",
    requirements_cache_dir="/tmp/pyflink_cache"
)

适合:numpy/pandas/requests 等依赖要在 worker 端安装。

6.3 add_python_archive:分发压缩包并解压到 worker 工作目录

python 复制代码
table_env.add_python_archive("/path/my_dep.zip", target_dir="deps")

适合:你打包了模型文件、词典、配置等资源,worker 端需要解压使用。

7. 配置入口:get_config(并行度、作业名、执行语义都在这)

table_env.get_config() 是你调参的总入口。

最常见的两类设置:

7.1 常规配置:并行度、作业名

python 复制代码
table_env.get_config().set("parallelism.default", "8")
table_env.get_config().set("pipeline.name", "my_first_job")

7.2 容错与状态:StateBackend、Checkpoint、Restart Strategy

现在推荐在 TableConfig 里配置(而不是只在 StreamExecutionEnvironment 配)。

python 复制代码
# 重启策略:fixed-delay
table_env.get_config().set("restart-strategy.type", "fixed-delay")
table_env.get_config().set("restart-strategy.fixed-delay.attempts", "3")
table_env.get_config().set("restart-strategy.fixed-delay.delay", "30s")

# Checkpoint:Exactly-once
table_env.get_config().set("execution.checkpointing.mode", "EXACTLY_ONCE")
table_env.get_config().set("execution.checkpointing.interval", "3min")

# StateBackend:rocksdb / hashmap
table_env.get_config().set("state.backend.type", "rocksdb")
table_env.get_config().set("execution.checkpointing.dir", "file:///tmp/checkpoints/")

经验建议:

  • 开 RocksDB 必须配 checkpoint dir(尤其是文件系统路径/对象存储路径)
  • 流作业一定要把 checkpoint 周期、超时、并发数等补齐到生产标准(这里只示例核心项)

8. Catalog 与 Module:多环境、多库、多函数体系的关键

当你接入 HiveCatalog、JDBC Catalog 或自研 Catalog 时,以下 API 很重要:

  • Catalog:register_catalog / get_catalog / use_catalog
  • Database:use_database / get_current_database
  • 列举对象:list_tables / list_views / list_functions / list_catalogs / list_databases ...
  • Module:load_module / unload_module / use_modules / list_modules

典型场景:

  • 你希望 SQL 里不写全限定名(catalog.db.table),就用 use_catalog/use_database 设置默认命名空间
  • 你希望扩展函数解析顺序,就用 module 管理

你可以把自己的项目按这个顺序组织(清晰且可维护):

1)创建 TableEnvironment(streaming/batch + config)

2)设置 TableConfig(并行度、checkpoint、statebackend、作业名)

3)注册 catalog / use catalog / use database(可选)

4)注册 source/sink(DDL 或 TableDescriptor)

5)注册 UDF + 依赖(如有)

6)sql_query 拿 Table 或 Table API 构建链路

7)execute_sql INSERT / Table.execute_insert / StatementSet.execute 提交执行

8)必要时 explain_sql/table.explain 看计划

相关推荐
Hello.Reader1 小时前
PyFlink Table API 用户自定义函数(UDF)通用 UDF vs Pandas UDF、打包部署、open 预加载资源、读取作业参数、单元测试
log4j·pandas
风送雨2 天前
八周Python强化计划(八)
开发语言·python·log4j
_OP_CHEN2 天前
【测试理论与实践】(八)吃透测试分类(下):阶段 + 执行 + 组织 + 地域,测试全维度分类指南
自动化测试·软件测试·测试开发·安全·log4j·测试开发工程师·测试分类
小代码20165 天前
loki 环境搭建
spring boot·docker·log4j·grafana
企鹅侠客5 天前
第07章—实战应用篇:List命令详解与实战(下)
windows·redis·log4j·list
小肖爱笑不爱笑7 天前
Maven
java·log4j·maven
垚森10 天前
【问题解决】关于log4j与logback依赖冲突的解决方案
log4j·logback·问题解决·依赖冲突
GA66666610 天前
2026 年自托管 Wiki 推荐:为什么选择 PowerWiki
人工智能·log4j·blog·wiki
cike_y12 天前
Mybatis之分页的实现&日志工厂&Log4j详解
数据库·log4j·mybatis