Presto 0.247 版本解读:QueryInterceptor、临时函数与分区统计优化的全面剖析 Presto 0.247 版本解读QueryInterceptor、临时函数与分区统计优化的全面剖析【免费下载链接】prestoThe official home of the Presto distributed SQL query engine for big data项目地址: https://gitcode.com/gh_mirrors/pre/presto导读本文基于 Presto 官方发布说明release-0.247.rst与仓库源码系统解读 Presto 0.247 版本的核心变更新增QueryInterceptor接口实现查询执行前后的自定义逻辑钩子、引入临时session-scoped函数能力以及 Hive 分区统计优化、Verifier HTTP 429 重试等工程改进。读者通过本文可以掌握该版本新增能力的使用方式、底层实现原理以及升级前需要关注的一个已知优化器缺陷。升级前必读一个可能被错误消除的优化器缺陷0.247 发布说明开篇即放置了一个醒目的警告warning自 0.246 版本由 :pr:14915引入了一个缺陷当查询使用GROUPING SETS (())、CUBE或ROLLUP时SORT或LIMIT可能被错误地消除。这意味着在这些聚合场景下查询计划中的排序或行数限制操作可能被优化器误判为冗余而裁剪导致结果集的顺序或条数不符合 SQL 语义。对于依赖多路分组集合聚合如报表中的小计/总计计算并叠加排序或限额的业务查询升级到 0.246 及之后版本时应重点回归验证该场景。该缺陷在 0.247 发布时仍然存在属于已知问题。Highlights0.247 的两大核心新特性1. QueryInterceptor在查询执行前后注入自定义逻辑0.247 在 JDBC 客户端层面新增了QueryInterceptor接口:pr:15565允许在查询执行之前或之后执行自定义逻辑。这是该版本最受关注的 JDBC 侧能力执行前可在查询提交到服务器之前对 SQL、会话参数或执行上下文进行预处理、审计或拦截执行后可在查询完成成功或失败后执行回调逻辑用于结果校验、耗时统计、日志采集等。从发布说明的归类看该接口同时出现在Highlights与JDBC Changes两个小节说明它主要面向通过 JDBC 驱动接入 Presto 的应用程序为客户端提供了一条标准化的查询生命周期扩展点适合做监控埋点、查询审计、SQL 改写等场景而无需修改服务端代码。2. 临时session-scoped函数会话级函数定义0.247 新增对**临时函数Temporary Function的支持函数作用域限定在当前会话session-scoped**内会话结束即失效不会产生持久化元数据。这在 Presto 的 SQL 函数定义语法中体现为TEMPORARY关键字。仓库中的 SQL 语法文档 create-function.rst 给出了完整语法骨架CREATE [ OR REPLACE ] [TEMPORARY] FUNCTION对应文档明确说明第 28-29 行WhenTEMPORARYis specified, the created function is valid and visible within the current session, but no persistent entry is made.即使用TEMPORARY创建的函数仅对当前会话可见且不会写入任何持久化条目。典型用法示例来自该文档第 90 行CREATE TEMPORARY FUNCTION square(x int)临时函数非常适合临时分析场景分析师可以在一次交互式会话中定义私有辅助函数用完即弃既不影响全局函数命名空间也无需管理员进行函数注册与发布流程。对应的 drop-function.rst 文档则覆盖了会话内函数的清理方式。General Changes通用引擎层改进缺陷修复数据规模上报、可撤销内存与 enum_key 竞态0.247 在通用引擎层修复了三类问题优化重分区optimized repartitioning的输出数据规模上报错误该修复保证查询执行统计中输出的数据量output data size能够真实反映优化后重分区算子的实际输出避免监控与成本核算数据失真可撤销内存revocable memory的记账缺陷此前的内存记账问题会导致部分查询在应当溢写spill到磁盘时没有触发溢写可能引发内存压力甚至 OOM修复后溢写决策所依赖的内存水位统计更加准确enum key 查找的竞态条件:pr:15607使用enum_key相关能力的查询偶发出现 internal error 崩溃根因是 enum key 查找过程中存在竞态该版本对此进行了修复。array_intersect 新增数组的数组输入实现0.247 为array_intersect新增了一个接受数组的数组array of arrays作为输入的实现扩展了该函数的表达能力。从当前仓库源码 ArrayIntersectFunction.java 可以看出该函数的实现细节它通过OptimizedTypedSet数据结构完成元素去重与交集运算并借助OperatorDependency(operator IS_DISTINCT_FROM)声明对元素类型的IS_DISTINCT_FROM操作符依赖从而支持任意可比较元素类型源码第 33-60 行ScalarFunction(array_intersect) Description(Intersects elements of the two given arrays) TypeParameter(E) SqlType(array(E)) public static Block intersect( TypeParameter(E) Type type, OperatorDependency(operator IS_DISTINCT_FROM, argumentTypes {E, E}) MethodHandle elementIsDistinctFrom, SqlType(array(E)) Block leftArray, SqlType(array(E)) Block rightArray) { ... OptimizedTypedSet typedSet new OptimizedTypedSet(type, elementIsDistinctFrom, rightPositionCount); typedSet.union(rightArray); typedSet.intersect(leftArray); return typedSet.getBlock(); }从源码结构可以推断该实现通过OptimizedTypedSet先对参与交集计算的一侧数组做 union 建集再以另一侧数组做 intersect整体基于类型化的 TypedSet 完成兼顾正确性与性能新增的数组的数组重载则进一步支持对嵌套数组类型进行交集运算。会话属性支持按 client info 正则匹配0.247 还支持通过 client info 上的正则表达式匹配来指定会话属性session properties进一步丰富了 Session Property Managers 的匹配维度。在该文档描述的会话属性匹配体系中此前已支持按user、source、group、clientTags等维度进行匹配而 0.247 引入了对clientInfo正则匹配的支持对应匹配表中的client_info_regex字段。文档中列举的匹配维度包括user可选与用户名的正则匹配source可选与 source 字符串的正则匹配group可选与查询所属资源组全限定名的正则匹配clientTags可选标签列表查询需携带全部标签才命中clientInfo可选与客户端提供的 client info 文本的正则匹配overrideSessionProperties可选布尔值指示会话属性是否覆盖客户端显式指定的会话属性。这意味着管理员可以依据客户端连接字符串中携带的 client info 内容例如渠道标识、应用版本、租户编号等为不同来源的客户端自动注入差异化会话属性实现精细化的会话级配置管理。SPI ChangesConnectorTableLayoutHandle 的标识扩展0.247 对 SPI 层做了一处向后兼容性增强在ConnectorTableLayoutHandle#getIdentifier中新增字段OptionalConnectorSplit split。从语义上看表布局句柄table layout handle的标识identifier此前用于区分不同的布局定义而新增的可选ConnectorSplit字段允许布局标识进一步绑定到具体的连接器分片信息。这为连接器在布局层面携带更细粒度的分片上下文提供了 SPI 通道对依赖布局标识进行结果缓存或计划复用的连接器实现具有重要意义。使用该接口的自定义连接器插件在升级后需要适配这一新字段。Hive Changes分桶表扫描与分区统计优化分组执行下的大分桶表扫描修复0.247 修复了一个 Hive 连接器的缺陷在使用**分组执行grouped execution**扫描大型分桶表bucketed tables时部分查询会以HIVE_EXCEEDED_SPLIT_BUFFERING_LIMIT错误失败。该错误通常与 split 缓冲上限有关分组执行会按桶对 split 进行分组处理当单个分组内的分片数量过多、超出缓冲阈值时即触发该异常。此修复保证了使用 grouped execution 处理大分桶表的查询能够稳定执行对依赖分桶表加速 Join/Aggregate 的 ETL 场景是重要的稳定性改进。基于分区统计的优化分区裁剪与列 domain 剥离0.247 为 Hive 连接器引入了基于分区统计partition stats的优化涵盖两个能力分区裁剪partition pruning利用分区级统计信息提前裁剪不可能包含命中数据的分区减少扫描量列 domain 剥离column domain stripping在分区统计基础上剥离与查询过滤条件无关的列 domain 信息为fragment 结果缓存fragment result caching提供更精确的缓存判定依据。这两个优化共同服务于一个目标——让基于 fragment 的结果缓存命中率更高、缓存键更准确从而在重复执行相同或相似查询时显著降低 Hive 侧的扫描开销。JDBC Changes客户端扩展点落地如前所述QueryInterceptor接口的引入同时被归入 JDBC Changes是 0.247 在 JDBC 客户端侧最重要的变化。对于使用 Presto JDBC 驱动构建数据平台、BI 工具或数据服务的团队可以通过实现该接口获得统一的查询生命周期钩子在不侵入服务端的前提下完成查询前参数化改写、敏感信息脱敏、配额与权限前置检查查询后耗时/结果集大小的观测、失败重试决策、审计日志落盘。Verifier Changes为 HTTP 429 增加查询重试Presto Verifier查询结果校验工具用于对比两套集群/两个版本的查询结果一致性在 0.247 中新增了对HTTP 429Too Many Requests错误的重试机制。当被校验集群因负载过高而返回 429 限流响应时Verifier 不再将该查询直接判定为失败而是按照重试策略重新发起查询避免因瞬时限流导致校验结果误报。这一改进提升了大规模批量校验任务在繁忙集群上的稳定性与结果可信度。Contributors0.247 的贡献者名单0.247 版本由以下社区成员贡献按发布说明收录Andrii Rosa、Ariel Weisberg、Arunachalam Thirupathi、Ashish Tadose、Bhavani Hari、Cem Cayiroglu、Daniel Ohayon、James Petty、James Sun、John Roll、Leiqing Cai、Marilyn Beck、Masha Basmanova、Mayank Garg、Rebecca Schlussel、Rob Peterson、Rongrong Zhong、Sean Wang、Shixuan Fan、Swapnil Tailor、Timothy Meehan、Wenlei Xie、Ying、Zhenxiao Luo、prithvip、tanjialiang。总结与升级建议Presto 0.247 是一个以可扩展性与稳定性为主题的版本扩展性QueryInterceptor与临时函数让客户端与会话层都能获得新的自定义能力稳定性修复了 repartitioning 上报、可撤销内存记账、enum_key 竞态、Hive 分桶表扫描等多处缺陷性能Hive 分区统计优化为 fragment 结果缓存提供了更精确的判定基础运维Verifier 的 429 重试提升了校验工具的可靠性。升级前请务必关注已知问题若业务中存在GROUPING SETS (())、CUBE、ROLLUP与SORT/LIMIT组合使用的场景应充分回归测试直至该缺陷在后续版本中修复。使用自定义连接器 SPI 的插件需要适配ConnectorTableLayoutHandle#getIdentifier的新字段使用会话属性管理的团队可同步评估基于clientInfo正则匹配的新维度。【免费下载链接】prestoThe official home of the Presto distributed SQL query engine for big data项目地址: https://gitcode.com/gh_mirrors/pre/presto创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考