PyFlink Debugging从“看不到日志”到“精准定位 UDF 性能瓶颈”

1. 日志体系:Client Side vs Server Side(别搞错位置)

1.1 Client Side Logging(提交端日志)

适用:UDF 之外 的代码,比如建表、拼 SQL、打印 schema、构建 pipeline 的过程。

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

env_settings = EnvironmentSettings.in_streaming_mode()
table_env = TableEnvironment.create(env_settings)

table = table_env.from_elements([(1, 'Hi'), (2, 'Hello')])

logging.warning(table.get_schema())
print(table.get_schema())

关键点:

  • Client 侧默认日志级别是 WARNING
  • 所以 logging.info(...) 通常你看不到,想看就用 warning/error 或调整 logging 配置

1.2 Server Side Logging(TaskManager 日志)

适用:Python UDF 内部,也就是你怀疑逻辑不对、数据不对、性能不对的时候。

python 复制代码
from pyflink.table import DataTypes
from pyflink.table.udf import udf
import logging

@udf(result_type=DataTypes.BIGINT())
def add(i, j):
    logging.info("debug info in TM log")
    print("debug print in TM log")
    return i + j

关键点:

  • Server 侧默认日志级别是 INFO
  • 你的 UDF 里的 logging.info 默认是能看到的(在 TaskManager 日志里)

2. 日志落盘位置:你到底去哪找

日志一般在:

  • $FLINK_HOME/log/

日志会写到 pyflink 模块目录下的 log 目录。官方给了一个一行命令直接定位:

bash 复制代码
python -c "import pyflink;import os;print(os.path.dirname(os.path.abspath(pyflink.__file__))+'/log')"

你可以把它作为博客里的"找日志最快方法"。

3. 调试 Python UDF:本地调试 vs 远程断点

3.1 Local Debug(本地 IDE 调试)

适合:你跑的是本地 mini cluster / 或者你只是想先把 Python 函数本身逻辑跑通。

做法:直接在 PyCharm/IDEA 的 Python 环境里对函数断点、单步即可。

建议小技巧:

  • 把 UDF 的核心逻辑提成普通 python 函数(纯函数),本地先测
  • 再包一层 udf/udtf/udaf 上到 Flink

3.2 Remote Debug(远程断点调试 UDF)

适合:UDF 真正在 TaskManager 上跑,你想"断点进去看运行时数据"。

步骤(你贴的内容我给你补成可跑的顺序):

  1. PyCharm 创建远程调试监听
  • Run -> Python Remote Debug -> + -> 选端口,比如 6789
  1. 安装 pydevd-pycharm
bash 复制代码
pip install pydevd-pycharm
  1. 在 UDF 里插入 settrace
python 复制代码
import pydevd_pycharm

pydevd_pycharm.settrace(
    'localhost',
    port=6789,
    stdoutToServer=True,
    stderrToServer=True
)
  1. 启动 PyCharm 的 Debug Server
  2. 提交/运行 Flink 作业
    断点命中后你就能看变量、堆栈、逐行执行。

实战注意点(经验坑位):

  • localhost 只有在"Python worker 能访问到你 PyCharm 所在机器"时才成立

    • 如果 Python worker 在远程机器/容器里,通常要改成你的开发机 IP,且确保端口可达
  • 分布式并行度 > 1 时,可能多个 subtask 同时尝试连 debug server

    • 初次建议把 parallelism 调成 1,先把链路跑通

4. Profiling:定位"慢到底慢在哪个函数"

官方给的是一个开关:

python 复制代码
t_env.get_config().set("python.profile.enabled", "true")

开启后,profiling 结果会周期性输出到 TaskManager 日志里。

实战建议:

  • Profiling 输出周期和你前面那套配置有关:python.fn-execution.bundle.sizepython.fn-execution.bundle.time 会影响"多久吐一次 profile"
  • 如果你 bundle 非常大,profile 可能很久才出一份;排障时可以先把 bundle 调小,让 profile 更快出现

5. 一套"排障顺序"你可以直接写进博客

  1. 先确认日志位置:用那条 python 命令定位 log 目录
  2. 先打 Client 侧日志:确认 schema、DDL、SQL 拼接、配置是否生效
  3. 再打 UDF 侧日志:在 TaskManager 日志里看数据是否符合预期
  4. 逻辑不对:上 Remote Debug 断点看真实输入输出
  5. 性能不对 :开 python.profile.enabled=true 看热点函数,再回头调 bundle/arrow/chaining/execution-mode
相关推荐
秋97 小时前
Go语言(Golang)开发工程师全景解析:岗位职责·语言优势与使用场景·各城市薪资·发展前景·高考志愿填报(2026版)
开发语言·golang·高考
无风听海7 小时前
多租户系统中的 OIDC:Discovery 端点与联合登录的深度实践
后端·python·flask
CTA终结者8 小时前
期货量化主力换月程序怎么移仓:天勤 underlying_symbol 与任务切换
python·区块链
huangdong_8 小时前
1688商品图片采集技术解析:登录态处理与SKU图自动分类
开发语言
马士兵教育8 小时前
Java还有前景吗?Java+AI大模型学习路线及项目?
java·人工智能·python·学习·机器学习
chase_my_dream8 小时前
C++ + SLAM 高频面试问题整理
开发语言·c++·面试
KaMeidebaby8 小时前
卡梅德生物技术快报|纯化重组蛋白实操详解
人工智能·python·tcp/ip·算法·机器学习
Cloud_Shy6188 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第五章 Item 30 - 32)
开发语言·人工智能·笔记·python·学习方法
天佑木枫9 小时前
15天Python入门系列 · 序
开发语言·python
happylifetree9 小时前
Python017-第二章15.数据容器-dict常用操作
python