Presto 整体介绍

2,042 阅读8分钟

Presto是一个分布式SQL查询引擎,用于查询分布在一个或多个不同数据源中的大数据集,完整安装包括一个Coordinator或多个Worker。由客户端提交查询,从Presto命令行CLI提交到Coordinator,Coordinator进行解析,分析执行查询计划,然后分发处理队列到Worker。

Presto特点

  1. Presto是完全基于内存的分布式大数据查询引擎,所有查询和计算都在内存中执行
  2. Presto的输入是SQL语句,输出是具体的SQL执行结果
  3. Presto可以对接不同的数据源,例如MySQL、Hive等
  4. Presto可以对SQL的处查询过程进行优化,包括SQL本身的执行计划优化,以及用分布式查询提高并发等
  5. Presto不是数据库,并不能处理在线事务

基本概念

Presto服务进程

Presto集群中一共有两种服务器进程:Coordinator服务进程和Worker服务进程,其中Coordinator服务进程的主要作用是:接收查询请求、解析查询语句、生成查询执行计划、任务调度和Worker管理。而Worker服务进程则执行被分解后的查询执行任务:Task

Coordinator

作用:

  • 对外负责管理集群与客户端的连接,并接收客户端查询请求
  • 进行SQL的语法解析、查询计划生成和优化,并进行查询任务的调度
  • 集群的管理节点,内置了discovery server,跟踪Worker节点的状态

部署情况:一般作为单独节点部署在集群中,如测试需求,可以与Worker节点部署一个节点

通信方式:使用Restful接口与客户端、Workers进行交互

Worker

作用:集群的工作节点,用于执行被分解后的查询任务(Task)及处理数据

部署情况:一般集群中部署多个worker节点

通信方式:使用Restful接口与Coordinator、其他Workers进行交互

交互关系

状态管理:Workers每隔一段时间会向Coordinator发送Restful心跳,告知Coordinator的Discover Server状态

数据处理:

  • Worker:负责从connectors拉取数据,并与其他workers进行中间数据的交互处理
  • Coordinator:负责从Workers拉取结果,并将最终结果返回给客户端 Coordinator接收到客户端查询后,从存活的Workers列表中选出合适的Workers进行运行Task

Presto模型

Presto可以通过多种不同类型的Connector访问多种数据源,目前支持的Connector包括:Hive、JMX、MySQL、Cassandra、PostgreSQL以及Kafka。

Connector

作用:Presto通过connector可以访问多种不同的数据源,connector相当于数据库访问的驱动 每种connector通过实现Presto的SPI接口实现数据源的标准接入

通过connector访问数据源

  • 在$PRESTO_HOME/etc/catalog/下创建配置文件:example.properties(后缀必须为properties)
  • 设置属性connector.name,必选属性,catalog manager通过该配置属性创建访问相应数据源的connector
  • 支持使用多个catalog使用相同的connector去访问两个相似的数据源,例如,可以再一个presto集群中配置两个catalog(都是使用Hive connector),用于访问两个Hive集群

Catalog

类似于MySQL中的一个数据库实例,Catalog可以包含多个schema,并且通过使用指定的connector访问指定的数据源,例如,通过配置Hive catalog来访问Hive数据源

Schema

类似于MySQL中的Database,用于管理表,一个catalog和一个schema可以唯一确定一组可查询的表集合

Table

与传统数据库中的Table含义是一样的,从数据源到表映射由connector指定

Presto查询执行模型

Presto在执行SQL语句时,将SQL语句解析为相应的查询,并在分布式集群中执行这些查询

1. Statement

Statement语句,其实就是输入的SQL语句,在Presto中语句(Statement)和查询(Query)是不同的概念,当Presto执行输入的SQL语句时,会根据SQL语句生成查询执行计划,进而生成可以执行的查询(Query),查询代表的是分布到所有的Worker之间执行的实际查询操作

2. Query

Query即查询执行,一个查询执行代表可以在Presto集群中运行的查询,是由运行在各个Worker上且各自之间相互关联的阶段(Stage)组成的。

一个查询执行由Stage、Task、Driver、Split、Operator和DataSource组成,这些组件间通过内部联系共同组成了一个查询执行,从而得到SQL语句表述的查询,并得到相应的结果集。

3. Stage

Stage即查询执行阶段,当Presto运行Query时,Presto会将一个Query拆分成具有层级关系的多个Stage,一个Stage就代表查询执行计划的一部分,

通常情况下,Stage之间是树状的层级结构,每个Query都有一个Root Stage,该Stage用于聚集所有其他Stage的输出数据,并将最终的数据反馈给终端用户,Stage并不会在集群中实际执行,它只是Coordinator用于对查询执行计划进行管理和建模的逻辑概念。每个Stage(除了Single Stage和Source Stage)都会有输入和输出,都会从上游Stage读取数据,然后将产生结果输出给下游Stage,Source Stage没有上游Stage,它从Connector获取数据,Single Stage没有下游Stage,它的结果直接输出给Coordinator,并由Coordinator输出给终端用户。

Stage类型:

  • Coordinator_only:这种类型的Stage用于执行DDL或者DML语句中最终的表结构创建或者更改
  • Single:这种类型的Stage用于聚合子Stage的数据输出数据,并将最终数据输出给终端用户
  • Fixed:这种类型的Stage用于接收其子Stage产生的数据并在集群中对这些数据进行分布式的聚合或者分组计算
  • Source:这种类型的Stage用于直接连接数据源,从数据源读取数据,在读取数据的时候,该阶段也会根据Presto对查询执行计划的优化完成相关的断言下发(Predicate PushDown)和条件多虑等。

按照数据的流向,越靠近数据源的Stage越处于上游,越远离数据源的Stage越处于下游

4. Exchange

Presto的Stage是通过Exchange来连接另一个Stage的,Exchange用于完成上下游的Stage之间的数据交换。

5. Task

Stage在逻辑上又被分为一系列的Task,这些Task则是需要实际运行在Presto的各个Worker节点上的。

在Presto集群中,一个查询执行被分解成具有层级关系的一系列的Stage,一个Stage又被拆分为一系列的Task,每个Task处理一个或者多个Split。每个Task都有对应的输入和输出,一个Stage被分解为多个Task,从而可以并行地执行一个Stage,Task也采用了相同的机制:一个Task也可以分解为一个或多个Driver,从而并行地执行一个Task

6. Driver

一个Task包含一个或者多个Driver,一个Driver其实就是作用于一个Split的一系列Operator的集合。Driver是Presto架构最底层的并行处理单元,每个Driver都有一个输入和一个输出。

7. Operator

一个Operator代表对一个Split的一种操作,例如过滤、加权、转换等。一个Operator依次读取一个Split中的数据,将Operator所代表的计算和操作作用于Split的数据上,并产生输出,每个Operator均会以Page为最小处理单位分别读取输入数据和产生输出数据,Operator每次只会读取一个Page对象,相应地,每次也只会产生一个Page对象。

8. Split

Split即分片,一个分片其实就是一个大的数据集中的一个小的子集,而Driver则是作用于一个分片上的一系列操作的集合,而每个节点上运行的Task,又包含多个Driver,从而一个Task可以处理多个Split,其中每一种操作均由一个Operator表示。

9. Page

Page是Presto中处理的最小数据单元,一个PAge对象包含多个Block对象,而每个Block对象是一个字节数组,存储一个字段的若干行,多个Block横切的一行是真实的一行数据,一个Page最大为1MB,最多16x1024行数据。

在Presto中一次查询执行会被分解为多个Stage,Stage与Stage之间是有前后依赖关系的。每个Stage内部又会进一步分解为多个Task,属于每个Stage的Task被均分在每个Worker上并行执行,在每个Task内部又会被分解为多个Driver,每个Driver负责处理一个Split,而且每个Driver由一系列前后相连的Operator组成,这里的每个Operator都代表针对于一个Split的一种操作。

参考: prestodb.io/overview.ht…
prestodb.jd.com/
zhuanlan.zhihu.com/p/111053544