Presto学习-presto介绍

时间:2023-02-03 00:51:40

1、presto基本概念

1、1 presto服务进程
presto集群中一共有两种服务器进程:coordinator服务进程和worker服务进程,其中coordinator服务进程的主要作用是:接收查询请求、解析查询语句、生成查询执行计划、任务调度和worker管理。而worker服务进程则执行被分解后的查询执行任务:task
coordinator
coordinator服务进程部署于集群中一个单独的节点上,是整个presto集群的管理节点,coordinator服务进程主要用于接收客户端提交的查询,查询语句解析,生成查询执行计划、stage和task并对生成的task进行调度。除此之外,coordinator还对集群中的所有worker进行管理,coordinator进程是整个presto集群的master进程,该进程既与worker进行通信从而获得最新的worker信息,又与client进行通信,从而接受查询请求,而所有的这些工作都是通过coordinator上的statementResource类提供的RESTful服务来完成的。
worker
在一个presto集群中,存在一个coordinator节点和多个worker节点,coordinator节点是管理节点,而worker节点就是工作节点,在每个worker节点上都会存在一个worker服务进程,该服务进程主要进行数据的处理以及task的执行,worker服务进程每隔一定的时间都会向coordinator上的RESTful服务发送心跳,从而告诉coordinator:我还活着,并接受你调度,当客户端提交一个查询的时候,coordinator则会从当前存活的worker列表中选择出适合的worker节点去运行task,而worker在执行每个task的时候又会进一步对当前task读入的每个split进行一系列的操作和处理

1、2 presto查询执行模型
presto在执行SQL语句时,将这些SQL语句解析成相应的查询,并在分布式集群中执行这些查询
statement
statement语句其实就是指我们输入的SQL语句,presto支持符合ANSI标准的SQL语句,这种语句由子句(Clause)、表达式(Expression)和断言(predicate)组成、
presto为什么将语句(statement)和查询(query)的概念分开呢?
因为在presto中,语句和查询本身就是不同的概念,语句指的是终端用户输入的用文字表示的SQL的语句,当presto执行输入的SQL语句时,会根据SQL语句生成查询执行计划,进而生成可以执行的查询(Query),而查询代表的是分布到所有的worker之间执行的实际查询操作
query
query即查询执行,当presto接收一个SQL语句并执行时,会解析该SQL语句将其转变成一个查询执行和相关的查询执行计划,一个查询执行代表可以在presto集群中运行的查询,是由运行在各个worker上且各自之间相互关联的阶段(stage)组成的
那么SQL语句与查询执行之间有什么不同?
其实很简单,你可以认为SQL语句就是提交给presto用文字表示的SQL执行语句,而查询执行则是为了完成SQL语句所表述的查询而实例化的配置信息、组件、查询执行计划和优化信息等。一个查询执行由stage、task、driver、split、operator和DataSource组成。这些组件之间通过内部联系共同组成一个查询执行,从而得到SQL语句表述的查询,并得到相应的结果集。
stage
stage即 查询执行阶段,当presto运行query时。presto会将一个query拆分成具有层级关系的多个stage,一个stage就代表查询执行的一部分,例如,当我们执行一个查询,从hive的一张表具有1亿记录的表中查询数据并进行聚合操作时,presto会创建一个Root Stage,该stage聚合其上游stage的输出数据,然后将结果输出给coordinator,并由coordinator将结果输出给终端用户。
通常情况下,stage之间是树状的层级结构,每个query都有一个Root Stage,该stage用于聚集所有其他stage的输出数据,并将最终的数据反馈给终端用户,需要注意的是,stage并不会再集群中实际执行,它只是coordinator用于对查询执行计划进行管理和建模的逻辑概念,每个stage(除了single stage和source stage)都会有输入和输出,都会从上游stage读取数据,然后将产生结果输出给下游stage,需要注意的是,source stage没有上游stage,它从coordinator获取数据。single没有下游,它的结果直接输出给coordinator,并由coordinator输出给终端用户。

presto中的stage共分为4种,具体介绍如下
coordinator_Only:这种类型的stage用于执行DDL或者DML语句中最终的表结果创建或者更改。
single:这种类型的stage用于聚合子stage的输出数据,并将最终数据输出给终端用户
fixed:这种类型的stage用于接受其子stage产生的数据并在集群中对这些数据进行分布式的聚合或者分组计算。
source:这种类型的stage用于直接连接数据源,从数据源读取数据,在读取数据的时候,该阶段也会根据presto对查询执行计划的优化完成相关的断言下发和条件过滤等。
exchange
exchange的字面意思就是交换,presto的stage是通过exchange来连接另一个stage的,exchange用于完成有上下游关系的stage之间的数据交换,在presto中有两种exchange:output Buffer和exchange client,生产数据的stage通过名为output buffer的exchange将数据传送给其下游的stage。(根据数据的流向,分为上下游,你可以将presto中的查询执行过程中的数据比喻成一条河流,那么产生数据的stage对于消费数据的stage来说,就是上游)消费数据的stage通过名为exchange client的exchange从上游stage读取数据。
如果当期的stage是source类型的stage。那么该stage则是直接通过相应的connector从数据源读取数据的,而该stage则是通过名为source operator的operator与connector进行交互的,例如,如果一个source stage直接从HDFS获取数据,那么这种操作不是通过exchange client来完成的,而是通过运行于driver中的source operator来完成的。
task
从前面的章节我们可以知道,stage并不会在presto集群中实际运行,它仅代表针对于一个SQL语句查询执行计划中的一部分查询的执行过程,只是 用于对查询执行计划进行管理和建模,stage在逻辑上又被分为一系列的task,这些task则是需要实际运行在presto的各个worker节点上的,
在presto集群中,一个查询执行被分解成具有层级关系的一系列的stage。一个stage又被分为一系列的task,每个task处理一个或者多个split,每个task都有相应的输入和输出,一个stage被分解成多个task,从而可以并行的执行一个stage,task也采用了相同的机制,一个task也可以被分解为一个或者多个driver,从而并行地执行一个task。
driver
一个task包含一个或者多个driver,一个driver其实就是作用于一个split的一系列operator的集合,因此一个driver用于处理一个split,并且生成相应的输出,这些输出由task收集并且传送给其下游stage中的一个task,一个driver拥有一个输入和一个输出
split
split即分片,一个分片其实就是一个大的数据集中的一个小的子集,而driver则是作用于一个分片上的一系列操作的集合,而每个节点上运行的task,又包含多个driver,从而一个task可以处理多个split,其中每一种操作均由一个operator表示,分布式查询执行计划的源stage通过connector从数据源获得多个分片,source stage对split处理完毕之后,会将输出传递给其下游stage,
当presto执行一个查询的时候,首先会从coordinator得到一个表对应的所有split,然后presto就会根据查询执行计划,选择合适的节点运行相应的task处理split
page
page是presto中处理的最小数据单元,一个page对象包含多个block对象,而每个block对象是一个字节数组,存储一个字段的若干行,多个block横切的一行的真实的一行数据,一个page最大为1MB,最多16*1024行数据,

presto中执行 一个查询一共分为7步:

1、客户端通过HTTP协议发送一个查询语句给presto集群的coordinator
2、coordinator接到客户端传递过来的查询语句,会对该查询语句进行解析,生成查询执行计划,并根据查询执行计划依次生成SqlQueryExecution、sqlStageExecution、HttpRemoteTask。coordinator会根据数据本地性生成对应的HttpRemoteTask
3、coordinator将每个task都分发到其所需要处理的数据所在的worker上进行执行,这个过程是通过HttpRemoteTask中的HTTPClient将创建或者更新task的请求发给数据所在节点上TaskResource所提供的RESTful接口,TaskResource接收到请求之后最终会在对应的worker上启动一个sqlTaskExecution对象或者更新对应的sqlTaskExecution对象需要处理的split。
4、执行处于上游的source stage中的task,这些task通过各种connector从相应的数据源中读取所需要的数据
5、处于上游stage中的task会读取上游stage产生的输出结果,并在该stage每个task所在worker的内存中进行后续的计算和处理
6、coordinator从分发task之后,就会一直持续不断地从single stage中的task获取计算结果,并将计算结果缓存到buffer中,直到所有计算结束
7、client从提交查询语句之后,就会不停地从coordinator中获取本次查询的计算结果,直到获得了所有的计算结果,并不是等到所有的查询结果都产生完毕之后一次全部显示出来,而是每产生一部分,就会显示一部分,直到所有的查询结果都显示完毕