Presto执行计划 - 分发Statement到不同的QueryExecution

Presto执行计划 - 分发Statement到不同的QueryExecution

阅读源码时梳理逻辑用,无阅读价值

获取QueryExecution

queryexecution表示一次查询执行,用于启动、停止与管理一个查询,以及统计这个查询的相关信息。

在 经过Antlr 4语法解析起进行语法分析后,最终生成了一个Node,然后转成Statement,然后再包装成PreparedQuery

再看后续代码,在 dispatchQueryFactory.createDispatchQuery()方法中对不同类型的Statement 进行分发处理,其中对应的类为:QueryExecutionFactory

io.trino.dispatcher.DispatchManager.createQueryInternal()
1
2
3
4
5
6
7
8
 preparedQuery = queryPreparer.prepareQuery(session, query);
// ....
DispatchQuery dispatchQuery = dispatchQueryFactory.createDispatchQuery(
session,
query,
preparedQuery,
slug,
selectionContext.getResourceGroupId());

Presto查询计划

Presto执行计划-生成计划

阅读源码时梳理逻辑用,无阅读价值

在创建 dispatchQuery 的最后,返回了一个LocalDispatchQuery,其构造函数最后一个参数调用了 SqlQueryExecution 的start()方法


Presto执行计划-词法语法分析

Presto执行计划-词法语法分析

阅读源码时梳理逻辑用,无阅读价值

如果要跟可以从上一节提交查询过程中client 发送给coordinator 的提交查询API (/v1/statement)开始跟

client初始提交query后,coordinator 创建了一个Query,然后组装nextUri 后直接response了,这时候 query 尚未排队,只有当client 来请求query状态了(/v1/statement/queued/{queryId}/{slug}/{token}),这时才将其加入到调度队列中


Presto查询计划主流程和基础概念

Presto查询计划

生成查询计划

生成查询计划 分为 语法分析、词法分析、语义分析、执行计划生成、执行计划优化、执行计划分阶段执行。

基本概念

Node

经过词法和语法分析后,会生成抽象语法树(AST),该语法树中的每一个节点都是Node(SQL语句的一部分,例如select部分,where部分),Node是一个抽象类,其实现类如下图,特别庞大:


Presto提交查询

Presto提交查询

阅读源码时梳理逻辑用,无阅读价值

提交查询的流程

Presto/Trino 客户端对查询语句的提交分三个步骤:

  1. 从指定的文件、命令行参数或者Cli窗口中获取需要执行的SQL语句。
  2. 将得到的SQL语句组装成一个RESTFul 请求,发送给Coordinator,并返回处理的response
  3. Client 会不停地循环分配获取查询结果,返回给终端显示/返回给JDBC connect,直到查询结果完全显示

cli提交查询的入口在:client 目录下的trino-cli 工程中,入口类io.trino.cli.Trino


kudu安装部署异常记录

kudu安装部署异常记录

init kudu failed the cpu on this system does not support sse4.2

判断主机/虚拟机是否支持 sse4_2 指令集:

1
grep -q sse4_2 /proc/cpuinfo && echo "SSE 4.2 supported" || echo "SSE 4.2 not supported“"

由于物理主机的CPU是支持该指令集的,所以只需要修改虚拟机的主机模式

Unable to init master catalog manager


Presto 动态数据源改造方案

Presto 动态数据源改造方案

Presto 数据源加载机制原生是基于文件系统的,从配置目录中加载 数据源配置文件,从而实现不同源的数据库连接,而且整个过程是在presto集群启动时执行。而我们需要动态的增加/删除 数据源,并且不重启整个presto集群,所以对presto 加载数据源部分做了改造:

  1. 对外新增两个EndPoint:增加数据源API 和 删除数据源API
  2. 数据源的配置从文件系统迁移到数据库
  3. 在不重启集群的前提下,动态更新presto 数据源连接信息

动态增加/删除数据源,新增catalog endpoint

新增两个接口,用于向presto/trino 动态的增加和删除数据源:

  • POST http://{presto-api-base-url}/v1/catalog/add

  • DELETE http://{presto-api-base-url}/v1/catalog/delete

处理的流程图:


Presto Connector Plugin 开发

Presto Connector plugin开发


Prest/Trino编译调试经验(持续补充)

Presto(trino)编译调试经验(持续补充)

将Trino二次开发和调试过程中遇到的问题进行记录

trino运行报错跟踪

Trino 使用一段时间报错:

1
2
3
4
5
6
7
8
9
10
11

Caused by: java.lang.NoClassDefFoundError: io/trino/memory/QueryContext$QueryMemoryReservationHandler
at io.trino.memory.QueryContext.<init>(QueryContext.java:111)
at io.trino.execution.SqlTaskManager.createQueryContext(SqlTaskManager.java:196)
at io.trino.execution.SqlTaskManager.lambda$new$0(SqlTaskManager.java:162)
at com.google.common.cache.CacheLoader$FunctionToCacheLoader.load(CacheLoader.java:168)
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3529)
at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2278)
at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2155)
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045)
... 81 more

重启后正常,应该是发包后没有重启,后续没有出现

trino 在idea下,无法debug运行,报错:jdk 下一些类找不到


Presto-Kudu-Connector-Support-Array

Presto-Kudu-Connector-Support-Array

Presto是支持Array数据类型的,由于上层应用需要用到Array数据类型,所以当使用不支持Array数据类型的Kudu 作为存储引擎时,需要改造下Kudu 的连接器:

主要的改造思路就是,insert时将数组转换为字符串进行存储,读取时将字符串转换为数组给Presto。

  1. 从数据库中查询出哪些列是array 和 decimal
  2. 在KuduMetadata中修改getColumnHandles、getTableMetadata、beginInsert 方法,使相应的列名支持array-decimal
  3. 修改 KuduPageSink 的appendColumn方法,如果是array 类型,将其转换为特殊字符分割的字符串存入列中
  4. 修改KuduRecordCursor 的getObject方法,如果当前field类型是array,那么将获取的值反向分割转成字符串
  5. 修改NativeKuduClientSession的addConstraintPredicates方法,支持decimal条件过滤

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×