Presto Client REST API 完整指南从 /v1/statement 协议到跨集群查询重试【免费下载链接】prestoThe official home of the Presto distributed SQL query engine for big data项目地址: https://gitcode.com/gh_mirrors/pre/presto本篇技术指南基于 Presto 官方文档与客户端/服务端源码系统讲解 Presto Client REST API 的完整协议包括POST /v1/statement提交查询、基于nextUri的拉取式结果获取、完整的请求/响应头语义、QueryResultsJSON 结构以及面向高可用的跨集群查询重试机制。读完本文你将能够不依赖任何 SDK直接用 HTTP 客户端实现一个可用的 Presto 查询客户端并理解 Presto 的 JDBC/CLI 底层是如何工作的。一、协议总览三个 HTTP 方法Presto Client REST API 的核心只由三个 HTTP 方法组成全部围绕查询语句的生命周期展开HTTP 方法端点作用POST/v1/statement请求体body中携带 SQL 查询字符串返回包含查询结果的 JSON 文档若还有更多结果文档中会包含nextUri属性GETnextUri指向的 URL获取下一批查询结果DELETEnextUri指向的 URL终止一个正在运行的查询其中DELETE语义对应“取消/终止查询”。在客户端实现 StatementClientV1.java 中取消查询正是通过向nextUri发送DELETE请求以及向partialCancelUri发送部分取消信号来实现的。二、查询处理流程一次完整的请求生命周期2.1 发起查询一次 Presto 查询请求以POST /v1/statement开始请求体是 SQL 查询字符串Content-Type 为text/plain; charsetutf-8。调用方必须通过X-Presto-User请求头指定会话用户同时还可以携带下文列举的一长串其他请求头。服务端处理该端点的核心代码位于 QueuedStatementResource.java。从客户端源码看一次 POST 请求的组装过程如下见 StatementClientV1.java 的buildQueryRequest将服务器地址拼接为/v1/statement路径将 SQL 文本作为text/plain请求体 POST 出去依次附加X-Presto-Source、X-Presto-Trace-Token、X-Presto-Client-Tags、X-Presto-Client-Info、X-Presto-Catalog、X-Presto-Schema、X-Presto-Session、X-Presto-Prepared-Statement、X-Presto-Transaction-Id等头。2.2 结果轮询循环nextUri 拉取模型Presto 采用**拉取式pull-based**结果获取模型与一次性返回全部结果的 REST 接口不同POST /v1/statement返回一个QueryResultsJSON 文档若文档中没有nextUri说明查询已结束无论成功还是失败无需再发起任何请求若文档中有nextUri说明还有更多结果待获取客户端应循环对nextUri发起GET请求直到响应中不再出现nextUri。从源码看客户端轮询逻辑StatementClientV1.java会读取currentStatusInfo().getNextUri()为空即代表查询完成否则构造 GET 请求继续拉取。值得注意的是客户端还实现了validateNextUriSource安全校验默认要求nextUri的 host 与端口必须与当前infoUri一致否则抛出 “Next URI host and port are different than current” 异常防止恶意或错误的重定向导致客户端向意外地址发送请求。2.3 失败与繁忙处理若初始请求返回HTTP 503表示服务端繁忙客户端应等待50100 毫秒后重试除 503 和 200 之外的任何 HTTP 状态码都意味着查询失败。客户端实现中对 503 的处理印证了这一点非 503 状态会被判定为CLIENT_ERROR并抛出异常只有 503 才进入可重试路径。2.4 错误判定规则/v1/statement的 POST 请求返回QueryResultsJSON 文档及一批响应头。判定查询成败的关键规则是若QueryResults文档包含error字段类型为QueryError则查询失败若没有error字段则查询成功。QueryError对象包含message、errorCode等错误信息具体字段可参考QueryError类位于 presto-client。2.5 结果数据的两种形态JSON 文本形态若文档的data字段存在则它包含一批数据行同时columns字段也必然存在描述查询返回的列名与类型。二进制形态binaryResults在初始POST /v1/statement请求的 URL 上附加binaryResultstrue查询参数即可请求二进制格式的结果。此时响应 JSON 中的data字段不会出现取而代之的是binaryData字段——一个由 base64 编码的页面page组成的列表每个页面都遵循 SerializedPage 格式服务端实现位于 presto-main/src/main/java/com/facebook/presto/server/protocol 相关响应提供类。2.6 status 字段的定位QueryResults文档中的status字段仅供人类阅读它只是服务端查询状态的一个提示与服务端真实查询状态并不同步绝不能据此判断查询是否结束。判断查询是否完成唯一可靠依据是nextUri是否存在。三、QueryResults 重要属性下表列出 REST API 返回的QueryResultsJSON 文档中最重要的属性完整字段请参考 QueryResults.java属性说明id查询的 IDnextUri若存在是后续GET/DELETE请求应使用的 URL若不存在查询已完成或已出错终止columns查询返回的列名与类型列表data查询返回的数据行列表每行本身是一个列表元素顺序与columns属性一致updateType人类可读的操作类型字符串。例如CREATE TABLE请求的updateType为 CREATE TABLESET SESSION为 SET SESSIONerror查询失败时包含QueryError对象的 JSON该对象包含message、errorCode及其他错误信息从 QueryResults.java 源码看该对象还包含文档表格之外的两个实用成员infoUricoordinator 上提供查询信息的 URI用于查询详情页/状态跟踪partialCancelUri当前正在执行的叶子 stage 的 URI用于发出部分取消信号。此外构造函数中有一处值得注意的校验逻辑data与binaryData同时为 null 时要求columns必须存在checkArgument((data null binaryData null) || columns ! null, data present without columns)并且data会经过FixJsonDataUtils.fixData处理——用于修复 JSON 反序列化时嵌套列如 array/map/row的表示问题这也是自定义客户端处理复杂类型数据时需要注意的细节。四、客户端请求头Client Request Headers下表完整列出 Presto Client REST API 支持的所有请求头。其中许多请求头会由响应头更新到客户端并在后续请求中回传行为类似浏览器 Cookie 机制。请求头名称说明X-Presto-User指定会话用户每次请求/v1/statement都必须提供X-Presto-Source供报告使用的、提交查询的软件名称X-Presto-Catalog运行查询所使用的 catalog由响应头X-Presto-Set-Catalog设置X-Presto-Schema运行查询所使用的 schema由响应头X-Presto-Set-Schema设置X-Presto-Time-Zone运行查询所使用的时区默认是 Presto 引擎的时区X-Presto-Language运行查询及格式化结果所使用的语言。可按查询粒度通过X-Presto-LanguageHTTP 头设置也可通过 JDBC 驱动的PrestoConnection.setLocale(Locale)方法设置会话语言X-Presto-Trace-Token向 Presto 引擎提供追踪令牌用于关联标识该查询请求产生的日志行X-Presto-Session以逗号分隔的namevalue会话属性列表。当客户端执行SET SESSION namevalue查询时该键值对会通过X-Set-Presto-Session响应头返回并加入客户端的会话属性列表若响应头X-Presto-Clear-Session返回其值就是要从客户端累积列表中移除的会话属性名X-Presto-Role设置本次请求使用的 catalog 角色由响应头X-Presto-Set-Role设置X-Presto-Prepared-Statement逗号分隔的namevalue列表name是先前准备好的 SQL 语句名称value是标识该预编译语句可执行形态的键X-Presto-Transaction-Id运行查询所使用的 transaction ID由响应头X-Presto-Started-Transaction-Id设置、由X-Presto-Clear-Transaction-Id清除X-Presto-Client-Info提交查询的客户端程序的任意信息X-Presto-Client-Tags逗号分隔的 tag 字符串列表用于标识 Presto 资源组resource groupX-Presto-Resource-Estimate逗号分隔的resourcevalue形式赋值列表。resource可选值EXECUTION_TIME、CPU_TIME、PEAK_MEMORY、PEAK_TASK_MEMORY。其中EXECUTION_TIME和CPU_TIME使用 airliftDuration字符串表示一个双精度数后跟TimeUnit字符串s秒、m分钟、h小时PEAK_MEMORY和PEAK_TASK_MEMORY使用 airliftDataSize字符串整数后跟B字节、kB千字节、mB兆字节、gB吉字节X-Presto-Extra-Credential向连接器connector提供额外凭据格式为namevalue字符串保存在会话的Identity对象中其 name 与 value 仅对连接器有意义X-Presto-Retry-Query布尔标志表示该查询是潜在重试的占位查询。设为true时在备份集群上将该查询标记为重试占位符并防止跨集群重试场景中出现重试链这些头全部在 PrestoHeaders.java 中定义为常量例如PRESTO_USER X-Presto-User、PRESTO_SESSION X-Presto-Session等客户端代码统一通过常量引用避免字符串散落。五、客户端响应头Client Response Headers收到响应后客户端必须根据响应头更新后续请求将使用的请求头保持一致。所有支持的响应头如下响应头名称说明X-Presto-Set-Catalog指示客户端在后续请求的X-Presto-Catalog请求头中设置 catalogX-Presto-Set-Schema指示客户端在后续请求的X-Presto-Schema请求头中设置 schemaX-Presto-Set-Session值为namevalue字符串表示对 Presto 引擎或连接器有意义的会话属性指示客户端将该键值对加入后续请求的X-Presto-Session请求头X-Presto-Clear-Session指示客户端从后续X-Presto-Session请求头的逗号分隔列表中移除名称等于该头值的会话属性X-Presto-Set-Role指示客户端将后续请求的X-Presto-Role请求头设置为该响应头值所给的 catalog 角色X-Presto-Added-Prepare指示客户端将namevalue键值对加入预编译语句集合用于后续请求的X-Presto-Prepared-Statement请求头X-Presto-Deallocated-Prepare指示客户端从预编译语句列表中移除名称等于该头值的预编译语句X-Presto-Started-Transaction-Id提供 transaction ID客户端应在后续请求的X-Presto-Transaction-Id请求头中回传X-Presto-Clear-Transaction-Id指示客户端清除后续请求使用的X-Presto-Transaction-Id请求头在客户端实现中这些响应头与请求头的“Cookie 式”联动由StatementClientV1的processResponse完成X-Presto-Set-Catalog/X-Presto-Set-Schema写入setCatalog/setSchemaX-Presto-Set-Session写入setSessionProperties并发 MapX-Presto-Clear-Session写入resetSessionProperties集合X-Presto-Started-Transaction-Id/X-Presto-Clear-Transaction-Id分别更新startedTransactionId与clearTransactionId。这些累积状态会在下一次请求构造时重新组装进请求头。六、QueryResults 数据成员源码级补充官方文档还列出了一些在排查问题时有用的QueryResults数据成员数据成员类型说明queryErrorQueryError仅当查询出错时为非空。QueryResults.failureInfo类型FailureInfo包含失败原因详情含堆栈轨迹FailureInfo.errorLocation提供检测到失败处的查询行号与列号warningsListPrestoWarning通常为空的警告列表statementStatsStatementStats包含查询执行统计信息的类尤其值得注意的是StatementStats.rootStage类型StageStats提供查询处理各 stage 的执行统计从 QueryResults.java 源码可以确认文档表格之外该对象还持有statsStatementStats即文档中的statementStats、updateCount查询更新的行数、warnings、binaryData等字段它们全部通过 Jackson 的JsonProperty序列化/反序列化。任何自定义客户端在解析时都应对这些字段保持“可空容忍”例如nextUri、columns、data、error、updateType、updateCount都是可空Nullable字段。七、PrestoHeaders全部协议头的常量定义类 PrestoHeaders.java 枚举了 Presto Client REST API 允许的所有 HTTP 请求头与响应头。除了上文两个表格中的头它还额外定义了X-Presto-Session-Function/X-Presto-Added-Session-Functions/X-Presto-Removed-Session-Function会话函数session function的注册与移除X-Presto-Current-State、X-Presto-Max-Wait、X-Presto-Max-Size、X-Presto-Buffer-Remaining-Bytes查询结果缓冲控制相关X-Presto-Task-Instance-Id、X-Presto-Page-Sequence-Id、X-Presto-Page-End-Sequence-Id、X-Presto-Buffer-Complete、X-Presto-Prefix-Url任务与分页协议相关。这套常量类是客户端与协议文档之间的“单一事实来源”实现自定义客户端时建议直接复用该常量类避免手写字符串导致大小写或连字符错误。八、跨集群查询重试Cross-Cluster Query RetryPresto 支持在主集群上查询失败时自动在备份集群backup cluster上重试查询。该特性通过把失败查询透明地重定向到备份集群来实现高可用。8.1 工作机理与查询参数当路由器或负载均衡器处理一个应支持跨集群重试的查询时它会在把客户端重定向到主集群时附带以下查询参数retryUrlURL 编码的备份集群端点。若查询失败可在该端点重试retryExpirationInSeconds重试 URL 的过期秒数必须至少为 1。该值应依据 Presto 查询端点返回的Cache-Control响应头来设置——Presto 用Cache-Control头指示查询在服务端内存中的保留时长重试过期时间不应超过该缓存时长以保证发生重试时占位查询仍然可用。两个参数必须同时提供如果只提供其中一个请求会被以400 Bad Request拒绝。服务端对retryUrl的安全性校验在 RetryUrlValidator.java 中实现从源码可见其校验维度包括是否要求 HTTPSrequireHttps配置、路径是否以指定重试路径开头、是否携带额外查询参数、域名是否在允许范围内等。向主集群发起请求的示例POST /v1/statement?retryUrlhttps%3A%2F%2Fbackup.example.com%3A8080%2Fv1%2FstatementretryExpirationInSeconds3008.2 重试头X-Presto-Retry-QueryX-Presto-Retry-Query头用于表示一个查询是“为重试而建的占位查询”。当设置为true时表明该查询是备份集群上的重试占位查询防止重试链——带此头的查询即使失败也不会再触发另一次重试。8.3 完整重试流程路由器/负载均衡器携带X-Presto-Retry-Query: true头向备份集群 POST 查询创建一个可作为重试目标的占位查询路由器以 HTTP 307 将客户端重定向到主集群并附带retryUrl与retryExpirationInSeconds查询参数客户端跟随重定向向主集群 POST 查询主集群正常执行查询若查询以可重试错误码失败错误码在服务端配置Presto 服务端会修改响应中的nextUri使其指向备份集群的重试 URL客户端跟随nextUri到达备份集群由占位查询真正执行原查询若重试查询失败由于它带有X-Presto-Retry-Query标记不会再触发另一次重试。8.4 适用范围与限制跨集群重试仅在所有结果尚未返回给客户端时才生效实际场景中适用于CREATE TABLE AS SELECT语句DDL 操作如CREATE、ALTER、DROPINSERT语句在产生任何结果之前就失败的SELECT查询。对于会产出结果的SELECT查询只有失败发生在计划阶段或第一批结果生成之前重试才会发生。九、实践手写一个最小客户端结合以上协议一个最小 Presto 客户端的骨架流程如下伪代码级描述可直接对照 StatementClientV1.java 实现细节构造POST http://coordinator:8080/v1/statementbody 为 SQL 文本携带X-Presto-User: 用户名以及可选的X-Presto-Catalog、X-Presto-Schema、X-Presto-Session等头若响应为 503等待 50100ms 后重试解析返回的QueryResultsJSON记录id检查error字段判断成败若有columns/data则消费结果将响应头中X-Presto-Set-*、X-Presto-Added-Prepare等头回填到后续请求循环若存在nextUri对其发起 GET注意校验 host/port 一致否则查询结束需要取消时对最新nextUri发起 DELETE。参考实现位于 presto-client 模块其测试用例presto-client/src/test/java/com/facebook/presto/client可作为协议行为的验证依据。十、参考路径速查协议文档presto-docs/src/main/sphinx/develop/client-protocol.rst结果对象presto-client/src/main/java/com/facebook/presto/client/QueryResults.java协议头常量presto-client/src/main/java/com/facebook/presto/client/PrestoHeaders.java客户端实现presto-client/src/main/java/com/facebook/presto/client/StatementClientV1.java服务端入口presto-main/src/main/java/com/facebook/presto/server/protocol/QueuedStatementResource.java重试 URL 校验presto-main/src/main/java/com/facebook/presto/server/RetryUrlValidator.java二进制结果页面格式presto-docs/src/main/sphinx/develop/serialized-page.rst【免费下载链接】prestoThe official home of the Presto distributed SQL query engine for big data项目地址: https://gitcode.com/gh_mirrors/pre/presto创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
大数据技术全解析:核心原理、应用场景与学习路线 你有没有发现,手机里的App好像越来越懂你了?晚上十一点打开外卖软件,排名前三的店铺恰好是你最近惦记的那几家;出门前看一眼导航,它连哪个路口马上要堵、哪条小路能省五分钟都替你算好了;甚至你还没体检&am… · 2026/9/23 3:07:45
baozi入门到精通:3步搞定项目搭建与选型避坑 baozi入门到精通:3步搞定项目搭建与选型避坑 刚背完语法却连个像样的项目都搭不起来?别慌,这是90%应届生和转行者的通病。 很多新人以为学会 if/else 或 for… · 2026/9/23 3:07:38
Posting 终端 API 客户端从安装到实战:uv/pipx 部署、双 UI 模式与纯键盘请求工作流 开发工具CLI 【免费下载链接】posting The modern API client that lives in your terminal. 项目地址: https://gitcode.com/gh_mirrors/po/posting 点击查看 免费下载 Posting 是一个运行在终端(TUI)里的现代化 API 客户端,它把… · 2026/9/23 3:55:52
重启人生指南:1天内用系统化流程夺回生活控制权 “我悟了!2亿人拜读的万字长文干货,如何在1天内重启你的人生?”这个标题,说实话,我第一次刷到的时候是有点嗤之以鼻的。又是“重启人生”,又是“1天”,这不就是典型的流量密码吗?但耐… · 2026/9/23 3:55:45
3步搞懂diang原理:从面试被问懵到最佳实践落地 3步搞懂diang原理:从面试被问懵到最佳实践落地 面试被问原理答不上来,这种尴尬我经历过太多次。刚转嵌入式开发那会儿,面试官盯着屏幕问:“这个diang信号怎么保证稳定?”我愣在原地,脑子里全是浆糊。其实不是概念难,是没人把底层逻辑和工程… · 2026/9/23 3:55:45
Akka Persistence 插件机制完全指南:可插拔的 Journal、快照存储与持久化查询后端 后端并发编程异步编程 【免费下载链接】akka-core A platform to build and run apps that are elastic, agile, and resilient. SDK, libraries, and hosted environments. 项目地址: https://gitcode.com/gh_mirrors/ak/akka-core 点击查看 免费下载 Akka Persis… · 2026/9/23 3:55:33
Salt 包管理器 spm 命令完全指南:从包构建、仓库管理到安装卸载的 CLI 实战 运维配置管理后端 【免费下载链接】salt Software to automate the management and configuration of infrastructure and applications at scale. 项目地址: https://gitcode.com/gh_mirrors/sa/salt 点击查看 免费下载 spm(Salt Package Manager&… · 2026/9/23 3:55:27
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29