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


kudu安装部署异常记录

kudu 管理运维常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
service kudu-master restart
service kudu-tserver restart

# master server 管理界面
http://presto-1:8050/tablets

# tablet server 管理界面
http://presto-2:8051/tablet-servers

# 列出集群中的 tablet server
kudu tserver list presto-1,presto-2,presto-3

# 列出集群中的 master server
kudu master list presto-1,presto-2,presto-3

# 查看指定tserver_address的状态
kudu tserver status <tserver_address>

# 检测集群状态
sudo -u kudu kudu cluster ksck presto-1,presto-2,presto-3
sudo -u kudu kudu cluster ksck presto-1,presto-2,presto-3 > ./ksck.out 2>&1
<!-- more -->
# 检查tserver_address的状态
sudo -u kudu kudu remote_replica check <tserver_address>

# 列出所有表
kudu table list presto-1:7051,presto-2:7051,presto-3:7051

# 删除表
sudo -u kudu kudu table delete presto-1:7051,presto-2:7051,presto-3:7051 table_name
events
metrics_kudu
#
kudu remote_replica copy <tablet_id> <src_address> <dst_address> [-force_copy]

修复replicas

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
sudo -u kudu kudu cluster ksck master1,master2,master3 > ./ksck.out 2>&1
发现有56个表处于非健康状态:
==================
Errors:
==================
table consistency check error: 56 out of 183 table(s) are not healthy

举例:
在ksck.out中可以看到具体是哪个表的哪个tablet出问题了:
The consensus matrix is:
Config source | Replicas | Current term | Config index | Committed?
---------------+--------------+--------------+--------------+------------
master | A B C* | | | Yes
A | A B C* | 1427 | 2450 | Yes
B | A B C* | 1427 | 2450 | Yes
C | A B C* | 1427 | 2450 | Yes
Tablet 3689e076ed354f94a0967d1eed4b7d16 of table 'impala::dl_zz_kudu.tm_scada_hdzysj_change' is unavailable: 2 replica(s) not RUNNING
868688d5077b4e02b14a8a0a57958668: TS unavailable
0b4f24052ed74405b5d58fecd83f33e7: TS unavailable
a59cf0d8d1ed45d8b1af094f4a28d686 (xxxxx:7050): RUNNING [LEADER]

0 replicas' active configs differ from the master's.
All the peers reported by the master and tablet servers are:
A = 0b4f24052ed74405b5d58fecd83f33e7
B = 868688d5077b4e02b14a8a0a57958668
C = a59cf0d8d1ed45d8b1af094f4a28d686

可以看到只有a59cf0d8d1ed45d8b1af094f4a28d686这一个replication是好的,另外俩都不可用了。
修复命令:
sudo -u kudu kudu remote_replica unsafe_change_config xxxx:7050 3689e076ed354f94a0967d1eed4b7d16 a59cf0d8d1ed45d8b1af094f4a28d686

sudo -u kudu kudu remote_replica unsafe_change_config xxxx:7050 {tablet_id} {replica_id}

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 下一些类找不到


Your browser is out-of-date!

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

×