
点击蓝字关注 Timeplus,拥抱实时数据分析
Timeplus 3.3.1内嵌了自由线程(free-threaded)版CPython 3.14。用户定义函数(UDF)、外部流和表函数不再因为Python全局解释器锁(GIL)而串行执行:8个并发Python UDF查询的耗时从10.09秒降到1.18秒。
同一条查询、同一台主机、同一个Python函数,唯一的变量是同时执行它的客户端数量:

在3.2.14上,客户端从1个增加到4个,耗时增加3.7秒;在3.3.1上,只增加69毫秒。曲线由明显增长变为接近水平,正体现了这次运行时升级的核心变化:在旧运行时中,每一个新增的Python查询都只是又一个等待执行的任务;在新运行时中,它们可以真正并发地运行在不同的核心上。

实际影响
GIL影响的是服务端所有需要执行Python字节码的路径,而不仅仅是用户自定义函数(UDF)。标量UDF、聚合UDF、Python外部流的source和sink、Python表函数,全都进入同一个内嵌运行时,因此不同类型的Python任务之间同样会相互阻塞,而不只是同类任务之间。一个在后台持续写入数据的Python外部流,会与另一条完全无关的查询中的Python UDF竞争同一个进程级GIL。
在实际系统中,这通常表现为:物化视图(MV)之间相互拖慢;或者某个打分UDF单独压测时表现正常,一旦承载真实流量就明显劣化。收益最大的是CPU密集的逐行Python计算:特征工程、自定义解析、地理与字符串变换、打分、模型推理。

运行时改动
Timeplus 3.3.1内嵌的是按自由线程ABI构建的CPython 3.14:
3.14.6, free_threaded=True, gil_enabled=False, abiflags=t在GIL构建下,任何一个进入Python的查询线程都必须先获取GIL才能执行字节码;DBMS线程再多,同一时刻也只有一个线程能够执行Python字节码。在自由线程构建下,线程仍然需要关联Python thread state,CPython内部仍然存在必要的同步机制,只是执行字节码时不再存在GIL这一全局串行化点。

上述结论可以通过Timeplus暴露的指标直接验证。在8客户端这一批测试中,PythonGILWaitMicroseconds从1.04秒的纯锁等待降至17微秒,同时两个版本进入Python运行时的次数相同,返回的校验和也相同。计算量完全一致,差别只在于消除了串行等待。

测试方法
测试使用一个刻意设计为CPU密集的标量UDF:每行执行600次纯Python循环迭代,不涉及IO,也不依赖任何第三方包。这样可以确保测量结果反映的是Python执行本身,而不是数据转换或传输开销。
两种测试场景,各运行3次,取中位数:
-- 查询之间的并发:N 个独立客户端,每个单线程SELECT sum(py_spin(number)) FROM numbers(30000) SETTINGS max_threads =1;-- 单条查询内部的并行:1 个客户端,N 个线程SELECT sum(py_spin(number)) FROM numbers_mt(2000000) SETTINGS max_threads =16;
第一种固定max_threads = 1,因此其并行度只能来自不同的会话。第二种使用numbers_mt(多线程生成器),因为普通numbers()只产生单个数据流,无法为max_threads提供可切分的并行来源。

一条查询,多个线程
多数场景下并不会真的运行8个并发客户端,更常见的是用一条查询扫描大量数据,依靠max_threads提升速度。这条路径同样会受到GIL的限制。

在3.2.14上,max_threads对Python字节码执行无法带来并行加速:Python字节码执行部分只能利用一个核心,无论设置1个线程还是16个线程,耗时都在82秒左右,甚至会略微变慢,因为额外的线程只增加了竞争,并没有提升吞吐。在3.3.1上,同一条查询可以利用16个核心,7.24秒完成,相同设置下快12倍。

升级前注意事项
自由线程版CPython使用独立的ABI。包含C扩展的Python包必须安装针对cp314t ABI构建的wheel;针对cp312或普通cp314(GIL版本)构建的包无法加载。
纯Python包不受此影响,现有Python源代码无需修改。
目前主流数值计算和机器学习生态已经支持cp314t构建。我们的测试套件也已验证以下包在cp314t环境下可用:
NumPy
pandas
PyArrow
SciPy
scikit-learn
PyTorch
Prophet
stumpy
openai
截至本次发布,以下上游项目尚未提供cp314t构建:
statsmodels
river
PyCaret
qlib
neuralforecast
statsforecast
zstandard
这些限制主要来自上游项目的构建发布进度,随着各项目维护者发布对应的cp314t构建版本即可解决。
示例:
SYSTEM INSTALL PYTHON PACKAGE 'scikit-learn''1.5.2';SYSTEM LIST PYTHON PACKAGES;

其他行为变化
此次升级还包含两项行为变化:
1. ABI不匹配错误处理
当Python包的ABI与当前解释器不兼容时,系统现在会返回明确的错误信息,并提示所需的Python解释器版本,而不是在import阶段直接触发段错误。
2. Python外部流和表函数取消行为
取消Python外部流或表函数现在采用协作式停止机制:
系统会在批次边界检查取消请求;
不会在Python调用执行过程中强制中断。
升级到Timeplus 3.3.1即可获得自由线程运行时。如果你的UDF、外部流或表函数依赖包含C扩展的第三方包,请在升级前确认这些包已提供cp314t构建版本。

感谢阅读

欢迎试用

作者简介
史皓航
Timeplus工程师
Timeplus已经将我们的核心引擎开源,邀请大家体验并为我们的项目点赞!
官网
timeplus.com
体验开源
http://github.com/timeplus-io/proton
联系我们
info@timeplus.com
Timeplus有着活跃的技术社区,欢迎加入我们的官方交流群,与我们进行实时数据分析方面的业务分享,我们将为你提供适合的解决方案。

(如需加入Timeplus微信交流群,请扫码添加小助手微信)

相关阅读

Timeplus 微信公众号
点击阅读原文免费注册

Timeplus 知乎平台
实时,强大,简单

点个“在看”,让实时数据分析更加自然

