news 2026/9/23 1:52:19

Presto Release 0.155 技术解析:查询正确性修复、内存优化与 Hive Avro 支持

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Presto Release 0.155 技术解析:查询正确性修复、内存优化与 Hive Avro 支持
  • 大数据
  • 数据库
  • 后端

【免费下载链接】presto

The official home of the Presto distributed SQL query engine for big data

项目地址:https://gitcode.com/gh_mirrors/pre/presto
点击查看免费下载

本指南基于当前仓库中的官方版本发布说明 release-0.155.rst,系统梳理 Presto(当前仓库版本为 0.300-SNAPSHOT)0.155 版本在通用查询引擎、Hive 连接器与 SPI 层面的全部变更,并结合仓库源码验证底层实现原理。读完本文,你将掌握这些变更的来龙去脉,理解 grouping sets、IN 谓词、外连接等正确性修复背后的执行计划逻辑,以及内存记账、map 聚合内存优化、Parquet 新读器、Avro 文件格式支持等能力的实际落地方式。

版本定位与变更概览

Release 0.155 是 Presto 演进过程中的一个常规功能性版本,其变更横跨三大模块:

  • General Changes(通用引擎):以正确性修复为主,附带内存记账调整、内存优化与协调节点(coordinator)CPU 开销削减;
  • Hive Changes(Hive 连接器):修复 Parquet 新读器的 schema 演进问题、Hadoop KMS 相关类加载问题,并新增 Avro 文件格式支持;
  • SPI Changes(插件接口):移除 legacy connector API,进一步收紧了连接器插件必须遵循的接口契约。

版本号 0.155 对应的是 2017 年左右的 Presto 发布节奏;当前仓库已演进到 0.300-SNAPSHOT(见 pom.xml),但下述 0.155 引入的能力多数至今仍在代码库中保留并持续完善,例如key_based_sampling系列会话属性(见 SystemSessionProperties.java),可以作为理解现代 Presto 行为演进的起点。

General Changes:查询正确性修复

本节是 0.155 的核心,四个正确性修复分别对应查询执行链路中的不同环节。

多个 grouping sets 解析为同一集合时结果错误

GROUP BY GROUPING SETS是 Presto 支持的多维聚合语法。当一条查询中多个 grouping set 经过规范化后解析为同一组分组列时(例如GROUPING SETS ((a, b), (a, b))或通过展开后产生重复集合的情况),0.155 之前会产生错误的聚合结果。

从源码结构看,grouping sets 的执行由GroupIdOperator承担:它以groupingSetMappings(每组映射将输入列映射到输出列)为基础,为每个 grouping set 生成独立的groupId块,再按groupId分组聚合(见 GroupIdOperator.java)。当多个 grouping set 映射到同一组列时,若去重与分组映射的处理顺序不当,就会导致行被归入错误的 group,从而产生错误结果。0.155 的修复即是在计划阶段/执行阶段对重复 grouping set 进行正确归一化处理。

map 与 IN 谓词组合时结果错误

map数据类型与IN谓词组合使用(例如WHERE map_col['k'] IN (1, 2))在 0.155 之前可能产生错误结果。这类问题通常源于类型转换与常量折叠阶段对 map 取值表达式的处理缺陷——map 下标取值为空(key 不存在)时的 NULL 语义在 IN 列表求值过程中被错误传播。该修复属于表达式求值层的正确性修正,测试上对应 presto-main 的表达式与谓词求值测试套件。

复杂连接条件的外连接编译失败

当外连接(OUTER JOIN)的 ON 条件较为复杂(例如包含多层函数嵌套或多种运算符组合)时,0.155 之前可能触发编译失败(compile failure)。Presto 的 join 执行默认走本地字节码生成路径(presto-bytecode模块负责字节码生成),复杂连接条件在代码生成时若出现类型转换或变量作用域处理缺陷,就会导致生成的字节码无法通过校验。0.155 修复了该编译路径,使复杂 join 条件可正常生成并执行。

提交阶段失败的错误信息改进

查询提交(commit)阶段发生失败时,0.155 改进了错误信息的可读性,使 DBA 与用户能够更准确地定位失败环节(例如是元数据提交、目录提交还是文件提交失败),降低排障成本。

General Changes:内存记账与聚合内存优化

内存记账修正:聚合、Top N 与 DISTINCT

0.155 修复了简单聚合(simple aggregation)、Top N 与 DISTINCT 查询的内存记账(memory accounting)问题。修复前这些查询算子实际占用的内存可能未被完整计入,导致内存管理在压力下不够准确;修复后这些查询可能报告比以前更高的内存使用量——这是记账口径变准确的直接体现,而非新的内存泄漏。在presto-main-baseMemoryTrackingContext与各算子updateMemory调用链中可以看到现代版本对内存记账的持续强化。

减少 map_agg / multimap_agg / map_union 的不必要内存占用

map_aggmultimap_aggmap_union三个聚合函数在 0.155 中通过复用中间状态与减少临时对象分配,降低了内存占用。以 MapAggregationFunction.java 为例,它通过MethodHandle注册 input/combine/output 三阶段函数并使用专用 accumulator 状态累积键值对;MultimapAggregationFunction(见 multimapagg/MultimapAggregationFunction.java)同样将键去重建立在TypedSet之上以控制重复键的内存膨胀。0.155 的优化目标正是减少这些路径中重复持有或过早物化的中间结构。

语法与功能调整

INCLUDING / EXCLUDING / PROPERTIES 改为非保留关键字

INCLUDINGEXCLUDINGPROPERTIES三个词在 0.155 中被调整为非保留关键字(non-reserved keywords)。这意味着它们不再占用标识符的合法命名空间,用户可以将它们用作表名、列名等标识符(例如SELECT * FROM "properties"或直接SELECT including FROM t),同时仍可作为表/分区属性语法(如SHOW CREATE TABLE输出的WITH (...)属性块,以及 Hive 表属性中的TBLPROPERTIES语义)中的关键字使用。这一调整降低了关键字对用户命名的干扰。

移除基于采样表的近似查询实验特性

0.155移除了基于采样表(sampled tables)计算近似查询的实验性功能。该特性曾是 Presto 早期用于快速近似分析的方案,通过系统化地对表进行采样来估计聚合结果。移除后,近似分析能力让位于approx_*系列精确近似函数(如approx_distinctapprox_percentile等)。

值得注意的是,采样相关能力并未整体消失:现代版本以key_based_sampling会话属性族的形式保留了采样能力——key_based_sampling_enabledkey_based_sampling_percentagekey_based_sampling_function(见 SystemSessionProperties.java),并存在KeyBasedSampler计划优化器(见 KeyBasedSampler.java)以及EvaluateZeroSample等采样相关计划规则。可以看出 0.155 移除的是"整表采样近似"这一实验路径,而采样语义本身在后续版本中演化为受控的关键字采样方案。

准确统计创建 page source 的时间

0.155 开始在指标中准确记录创建 page source(数据页源)所花费的时间。page source 是 Presto 在物理执行计划中为表扫描等数据来源建立的页生产者,其创建耗时此前被笼统归入其他阶段。修复后,运维人员可以在查询统计信息中区分"数据源构建"与"实际读取"两个阶段的耗时,更精确地定位扫描性能瓶颈。

降低协调节点 CPU 占用的若干优化

0.155 包含多项面向 coordinator 的 CPU 优化,包括减少不必要的计划克隆、优化任务状态轮询与心跳处理的常数开销等。此类优化通常不可从单条 SQL 观察到,但在集群规模较大、查询并发较高时对协调节点的吞吐与延迟有实际收益。

Hive Changes:Parquet、KMS 与 Avro

新 Parquet 读器修复 schema 演进

0.155 修复了新 Parquet 读器(new Parquet reader)在 **schema 演进(schema evolution)**场景下的支持问题。schema 演进指底层 Parquet 文件与当前表 schema 不一致(如新增列、列类型放宽)时仍能正确读取。修复前,新读器在处理演进后的 schema 时可能发生类型映射或列裁剪错误;修复后行为与旧读器对齐。当前仓库中该能力沉淀于 presto-parquet 模块,其中包含 170 个主代码文件,ParquetReader与其测试套件覆盖了复杂 schema 与演进场景。

Hadoop KMS 的 NoClassDefFoundError 修复

使用 Hadoop KMS(Key Management Server,用于透明加密的密钥管理服务)时,0.155 之前可能出现NoClassDefFoundError。这通常是因为 KMS 相关类(如org.apache.hadoop.crypto.key.kms.*)在特定类加载环境下未被正确初始化或依赖缺失。修复通过调整 Hive 连接器对 Hadoop 安全组件的类加载顺序/依赖声明解决,使启用 KMS 加密的表可正常读写。

新增 Avro 文件格式支持

0.155 为 Hive 连接器新增 Avro 文件格式支持,这是本版本 Hive 侧最重要的功能增量。在 HiveStorageFormat.java 中,AVRO枚举将 Hive 侧的AvroSerDeAvroContainerInputFormatAvroContainerOutputFormat组合起来,并声明了 64MB 的默认压缩缓冲阈值:

AVRO( AvroSerDe.class.getName(), AvroContainerInputFormat.class.getName(), AvroContainerOutputFormat.class.getName(), new DataSize(64, Unit.MEGABYTE)),

这意味着用户可以直接创建 Avro 格式的 Hive 表:

CREATE TABLE events_avro ( event_id BIGINT, event_type VARCHAR, payload VARCHAR ) WITH ( format = 'AVRO' );

与 Avro 配套的 schema 管理同样贯通:HiveMetadata中定义了AVRO_SCHEMA_URL表属性,并规定只有当存储格式为 AVRO 时才能指定该属性,否则抛出INVALID_TABLE_PROPERTY错误(见 HiveMetadata.java)。读取已存在 Avro 表时,schema URL 会从 metastore 表参数(AVRO_SCHEMA_URL_KEY)中取出并还原为表属性(同文件 HiveMetadata.java)。因此,使用外部工具(如 Hive 或 Spark)创建的 Avro 表,只要其 schema 注册在 Hive Metastore 中,Presto 即可直接查询。

DWRF 字典编码流始终产出字典块

0.155 还保证DWRF(Facebook 优化的 ORC 变体)字典编码流始终产出字典块(dictionary blocks)。DWRF 对字典编码的流在读取时若直接解出原始值而非保持字典形式,会失去下游(如谓词下推、向量化计算)利用字典的能力。0.155 修复后,读取 DWRF 字典流时统一保持 dictionary block 形态,从而保住压缩与计算效率。

SPI Changes:移除 legacy connector API

0.155 的 SPI 变更只有一条,但影响面最大:彻底移除 legacy connector API

在此之前,Presto SPI 同时保留了一套"传统"连接器接口与一套新式接口(围绕ConnectorMetadataConnectorSplitManagerConnectorPageSourceProvider等按职责拆分的设计),legacy API 用于兼容早期插件。0.155 将 legacy 接口删除,意味着:

  • 第三方连接器插件必须实现新式 SPI 接口,否则无法加载;
  • 插件开发者升级到 0.155 时,需要将连接器代码迁移到以ConnectorMetadata/ConnectorSplitManager/ConnectorPageSourceProvider/ConnectorRecordSetProvider等为核心的 SPI 模型。

当前仓库的 presto-spi 模块(519 个主代码文件)即为这一新式 SPI 契约的完整体现,所有内置连接器(Hive、Iceberg、Kafka、Pinot 等)均遵循该契约实现。

升级与验证建议

针对要升级到 0.155 及之后的部署,结合本版本变更给出如下实操建议:

  1. 回归重复 grouping sets 查询:对线上GROUPING SETS/ROLLUP/CUBE查询做结果比对,确认聚合正确性修复未引入行为变化(该修复只影响重复集合的查询,正常查询不受影响)。
  2. 关注内存指标上涨:升级后简单聚合、Top N、DISTINCT 查询的 reported memory 可能上升,这是记账修正的结果,需按新口径调整内存告警阈值。
  3. 避免保留关键字冲突:由于INCLUDINGEXCLUDINGPROPERTIES变为非保留关键字,此前因关键字冲突而加引号的标识符可以简化;反之无需任何改动。
  4. Hive 侧验证:对新 Parquet 读器下的 schema 演进表执行扫描测试;若使用 KMS 加密,验证读写正常;如需使用 Avro 格式,可通过format = 'AVRO'建表并配合avro_schema_url属性指定 schema。
  5. 插件兼容性检查:任何第三方连接器需确认已迁移到新式 SPI,legacy 接口在 0.155 已不可用。

延伸阅读

  • 版本发布说明原文:release-0.155.rst
  • 后续版本发布说明目录:presto-docs/src/main/sphinx/release
  • 新式 SPI 契约:presto-spi
  • Parquet 读器实现:presto-parquet
  • Hive 存储格式枚举:HiveStorageFormat.java
  • Avro 相关表属性处理:HiveMetadata.java
  • 大数据
  • 数据库
  • 后端

【免费下载链接】presto

The official home of the Presto distributed SQL query engine for big data

项目地址:https://gitcode.com/gh_mirrors/pre/presto
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/23 1:52:11

手写实现中国外汇交易模块,这5个坑让你少走三年弯路

手写实现中国外汇交易模块,这5个坑让你少走三年弯路 刚学会 Python 或 Java 语法,盯着屏幕发呆,心里就一个念头:语法我都背下来了,为什么还是搭不起一个像样的项目?很多刚入行的开发者,在 CSDN 等社区翻遍了教程,却依然卡在“从 Hello World…

作者头像 李华
网站建设 2026/9/23 1:52:09

上标怎么打底层逻辑拆解,新手避坑指南

上标怎么打底层逻辑拆解,新手避坑指南 看了一堆教程还是不会写项目?别急,这不是你笨,是那些文章只教你按哪个键,没告诉你浏览器到底怎么渲染这个小小的“2”。 很多前端新手在实现化学式 H₂O 或数学公式 x² 时,习惯性地用 <sup> 标签,或者疯狂尝试 font-size…

作者头像 李华
网站建设 2026/9/23 1:52:02

一文搞懂NIS认证与施工资质:3个坑别踩

一文搞懂NIS认证与施工资质:3个坑别踩 复制来的代码跑不通,报错信息一堆,改了半天逻辑还是不对?别急,先别盯着屏幕死磕。很多开发者甚至项目负责人的痛点,不在于代码本身有多复杂,而在于 环境配置、依赖版本、底层协议 这些“看不见”的东西没对齐。 在编程圈,我们常说“Garbage In,…

作者头像 李华
网站建设 2026/9/23 1:51:46

Bi-LSTM+注意力+对抗训练:景区评论情感分析实战

简介&#xff1a;这份资源面向深度学习与自然语言处理方向的本科或研究生&#xff0c;尤其是正在准备情感分析类毕业设计的学生。它提供了一套基于融合对抗训练与注意力机制的Bi-LSTM网络&#xff0c;用于景区评论情感分析的完整Python实现&#xff0c;覆盖从数据标注、word2ve…

作者头像 李华
网站建设 2026/9/23 1:51:34

3招搞定还原魔方:从入门到精通避坑指南

3招搞定还原魔方:从入门到精通避坑指南 复制来的还原魔方代码跑不通,看着满屏报错却不知从何下手?别慌,这正是无数初学者从 入门到精通 路上必须迈过的一道坎。…

作者头像 李华