一、Presto
项目环境:
hadoop-3.3.0 安装路径:/usr/local/Cellar/hadoop/3.3.0/
启动方法:https://www.cnblogs.com/xym4869/p/8821312.html
hive-3.1.2 下载地址:http://www.apache.org/dyn/closer.cgi/hive/ 安装路径:/usr/local/hive
初始化代码:schematool -dbType mysql -initSchema
,同时lib文件夹下要有jdbc连接jar包
presto-0.219 安装路径:/opt/presto/presto-server-0.219/
服务端启动方法:sudo ./launcher start
客户端启动方法: ./presto --server localhost:8081 --catalog mysql
hive: hive --service metastore 和服务端
若docker启动无反应解决方法:
killall Docker && open /Applications/Docker.app
1.1 背景
Hadoop中的MapReduce(分布式计算框架)不能满足大数据快速实时adhoc查询计算的性能要求,Facebook2012年开发,2013年开源
presto是一个开源的用于大数据的高性能分布式sql查询引擎。
名词解释:
ad-hoc:即席查询,信息学的一个术语,用户根据自己的需求,灵活的选择查询条件,系统能够根据用户的选择生成相应的统计报表。即席查询与普通应用查询最大的不同是定制开发的,而即席查询是由用户自定义查询条件的。
个人对即席查询的理解:
尽可能快的执行自定义的SQL语句(无法提前运算和预测的sql语句,也就是无法提前优化的百万数据sql查询的快速响应)
重点关注
1.数据存储格式
2.缓存/索引
OLAP:数据分析的目标则是探索并挖掘数据价值,作为企业高层进行决策的参考,通常被称为OLAP(On-Line Analytical Processing,联机分析处理)。
**OLTP:**业务类系统主要供基层人员使用,进行一线业务操作,通常被称为OLTP(On-Line Transaction Processing,联机事务处理)。
从功能角度来看,OLTP负责基本业务的正常运转,而业务数据积累时所产生的价值信息则被OLAP不断呈现,企业高层通过参考这些信息会不断调整经营方针,也会促进基础业务的不断优化,这是OLTP与OLAP最根本的区别.
MPP:大规模并行处理
MPP本质上是(基于)数据库,基于传数据库并区别于传统单节点数据库,支持多节点分布式存储和计算。(另外,并不是所有的数据库集群方案都是基于分布式存储的)
MPP应该是多用作数据仓库,支撑查询和分析类应用场景。(个人理解)。
如果用关系型数据库(例如Mysql),搭建一个分布式存储和计算的多节点集群,就基本形成了一个MPP数据库系统。
1.2 使用presto的优点
多数据源、支持SQL、扩展性(可以自己扩展新的connector)、混合计算(同一种数据源的不同库 or表;将多个数据源的数据进行合并)、高性能、流水线(pipeline)
1.3 presto的缺点
不适合做多个大表的join操作;因为presto是基于内存的,若数据量过于庞大,将全部表数据装载至内存将导致任务无法执行。
若一个presto查询时间超过30分钟,那就kill吧,说明该语句不适合使用presto进行查询,同时也违背了presto的实时初衷
二、presto数据模型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KrKgmNJh-1615343218510)(/Users/wangdong/Library/Application Support/typora-user-images/image-20210303211011630.png)]
2.1 catalog
对应某一类数据源,例如hive的数据,或mysql的数据
2.2 schema
相当于MySQL的数据库,
2.3 table
table 对应mysql中的表
2.5列式存储
由于OLAP查询的特点,列式存储可以提升其查询性能,但是它是如何做到的呢?这就要从列式存储的原理说起,从图1中可以看到,相对于关系数据库中通常使用的行式存储,在使用列式存储时每一列的所有元素都是顺序存储的。由此特点可以给查询带来如下的优化:
-
查询的时候不需要扫描全部的数据,而只需要读取每次查询涉及的列,这样可以将I/O消耗降低N倍,另外可以保存每一列的统计信息(min、max、sum等),实现部分的谓词下推。
-
谓词下推:基本思想即:将过滤表达式尽可能移动至靠近数据源的位置,以使真正执行时能直接跳过无关的数据。
-
select item.name, order.* from order , item where order.item_id = item.id and item.category = ‘book’ /*使用谓词下推,会将表达式 item.category = ‘book’下推到join条件order.item_id = item.id之前。再往高大上的方面说,就是将过滤表达式下推到存储层直接过滤数据,减少传输到计算层的数据量。*/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iocW2Rp3-1615343218522)(file:///Users/wangdong/Library/Application%20Support/typora-user-images/image-20210303225653786.png?lastModify=1614783407)]
-
-
由于每一列的成员都是同构的,可以针对不同的数据类型使用更高效的数据压缩算法,进一步减小I/O。
-
由于每一列的成员的同构性,可以使用更加适合CPU pipeline的编码方式,减小CPU的缓存失效。
2.4 Page结构图!
Page可以理解为一张Table的一个数据子集,Page是由多个Block组成,每个Block为单一类型,例如Int Block, Long Block, Varchar Block等,其代表了Table中的某一列中的部分数据,因此Presto也被称为列式存储。
page是presto中处理的最小数据单元,一个page对象包含多个block对象,而每个block对象是一个字节数组,存储一个字段的若干行,多个block横切的一行的真实的一行数据,一个page最大为1MB,最多16*1024行数据。
个人理解:presto从MySql数据源中读取来数据后,根据sql列不同的类型,将mysql数据按block列存储(参考2.5 列式存储)
presto的存储单元包括:
- Page: 多行数据的集合,包含多个列的数据,内部仅提供逻辑行,实际以列式存储。
- Block:一列数据,根据不同类型的数据,通常采取不同的编码方式,了解这些编码方式,有助于自己的存储系统对接presto。
三、presto查询执行模型
流程如下:用户发起查询请求query->coordinator进行物理查询计划->逻辑查询计划->进入presto将其拆分为不同的stage->exchange下传-》Task接受数据-》交由Driver-》一个Driver负责一个split->Operator具体负责处理
-
Statement语句 其实就是输入的SQL
-
Query
-
根据SQL语句生成查询执行计划,进而生成可以执行的查询(Query),一个查询执行由Stage、Task、Driver、Split、Operator和DataSource组成
注:当Presto调度一个query时,coordinator节点会查询连接器的SPI接口获得一个表可用的所有split集合。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KWt74z1S-1615343218525)(/Users/wangdong/Library/Application Support/typora-user-images/image-20210303210832207.png)]
- Stage(阶段)
即查询执行阶段,一个 Query 会被拆分成具有层级关系的多个 Stage, 一个 Stage 代表查询执行计划的一部分。
Stage 不会在集群中实际执行,它只是 Coordinator用于对查询执行计划进行管理和建模的逻辑概念。
Stage之间是树状结构。- Coordinator_only
执行ddl,dml表结构创建和修改。 - Single
聚合子Stage结果,并将最终数据返回给客户端程序。 - Fixed
用于接收子Stage数据,并在集群中对这些数据进行聚合和分组操作。 - Source
接收数据源数据,会进行数据过滤,谓词下推。
- Coordinator_only
- Exchange(交换)
用于连接不同的Stage,用来完成有上下游关系的Stage之间的数据交换。- ExchangeClient
获取上游Stage产生的数据,供当前Stage使用 - OutputBuffer
缓存当前Stage生成的数据,供下游消费
- ExchangeClient
- stage 并不会被执行,只是对执行计划进行管理,一个stage代表执行计划的一部分
- Task(任务)
每个Stage 由多个 task 组成,task 实际运行在worker节点上,称之为一个任务;
每个Task 有对应的输入输出;
多个Task 并行执行一个 Stage,处理一个或多个 Split;
Driver(驱动)
每个Task 包含多个Driver,每个Driver 是对一个 Split 的Operator 操作集合;
一个Driver 处理一个 Split,拥有一个输入和输出。
是Presto 最底层的并行处理单元。
Operator(算子)
代表对一个 Split 的一种操作,例如过滤,关联,聚集等;
以Page 为最小处理单位进行数据的读取和输出; - Split(分片)
一个大数据集中的一个小的子集;
通过 Coordinator 获取表所对应的 split信息,然后指定查询计划,选择合适的worker处理对应的 Split; - Page(页)
是数据处理的最小单元;
一个Page 对象包含多个 Block 对象,一个Block 对象是一个字段的多行数据;
一个 Page 最大为 1M,最多 16*1024行; - Page presto中处理的最小数据单元 一个page包含多个block对象,每个block对象是个字节数据
一个查询分解为多个stage 每个 stage拆分多个task,每个task处理一个or多个split ,一个task被分解为一个或多个Driver,一个Driver去处理一个split
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WSSVhtRr-1615343218525)(/Users/wangdong/Library/Application Support/typora-user-images/image-20210301163113468.png)]
从图1-2中可以看到,在Presto 中一次查询执行会被分解为多个 Stage,Stage与 Stage之间是有前后依赖关系的。每个Stage内部又会进一步地被分解为多个Task,属于每个Stage的 Task 被均分在每个 Worker上并行执行。在每个Task内部又会被分解为多个Driver,每个Driver 负责处理一个 Split,而且每个Driver由一系列前后相连的Operator组成,这里的每个 Operator 都代表针对于一个 Split 的一种操作。
四、硬件架构
Presto 是一个完全基于内存的分布式查询执行引擎,因此Presto集群的硬件选择必须满足大内存、万兆网络和高计算能力的特点。由于 Presto 集群中的服务主要分为两种∶ Coordinator和 Worker,因此Presto 集群是 Master-Slave的拓扑结构。除此之外,想要成功地使用 Presto,还需要具有客户端。
CLI客户端∶ 部署了Presto 命令行客户端的服务器。
应用客户端∶开发人员可以使用Presto 的JDBC 驱动程序,通过 Java代码使用 Presto进行大数据查询和计算。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8RWlRfgE-1615343218526)(/Users/wangdong/Library/Application Support/typora-user-images/image-20210301163537684.png)]
五、软件架构!
presto 查询引擎是一个Master-Slave的拓扑架构
-
Presto 对多数据源的支持、数据源解耦以及易于扩展性归功于Presto的Connctor设计。在Presto 中,每种类型的数据源对应一种类型的 Connector,Presto 提供了SPI, Presto 的Developer只需要实现 SPI中提供的接口,就可以开发出从期望的数据源中读取数据的 Connector。
-
Presto是完全基于内存的分布式大数据查询执行引擎,所有的查询和计算均在内存中执行。
-
Presto 基于 PipeLine进行设计,每一次的查询都会被分解为多个分布在各个 Worker上的Task,每个Task都会与其上下游 Stage中的 Task在数据流上存在前后依赖关系,每个 Task 又会被进一步细分为多个 Driver,每个 Driver 由一系列有前后关系的 Operator 组成,每种 Operator 代表作用于一个 Split上的一种操作。每当查询启动的时候,就会在每个Worker上启动相应的Task,每个Task都会处理一个或者多个Split,并且每处理一个Buffer大小的数据量时,就会将结果传输到下游 Stage的 Task中,这样基本可以保证数据实时动态地传输。
-
Presto客户端提交查询语句至 Coordinator,Coordinator 将查询最终分解为 Task,并交由各个Worker执行,Coordinator 从Single Stage中的Task获得最终的查询结果,并将查询结果返回给客户端。
综上所述,Presto 的软件架构如图1-4 所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NgwZQqJC-1615343218528)(/Users/wangdong/Library/Application Support/typora-user-images/image-20210301164043579.png)]
从图 1-4中可以看到,在 Presto 中执行一个查询一共分为7步∶
- (1)客户端通过 HTTP协议发送一个查询语句给 Presto 集群的 Coordinator。
- (2)Coordinator 接到客户端传递过来的查询语句,会对该查询语句进行解析,生成查询执行计划,并根据查询执行计划依次生成 SqlQueryExecution、SqlStageExecution、 HtpRemoteTask。Coordinator 会根据数据本地性生成对应的 HttpRemoteTask。
- (3)Coordinator 将每个 Task 都分发到其所需要处理的数据所在的Worker上进行执行。这个过程是通过 HtRemoteTask 中的 HtpClient 将创建或者更新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 中获取本次查询的计算结果,直到获得了所有的计算结果。并不是等到所有的查询结果都产生完毕之后一次全部显示出来,而是每产生一部分,就会显示一部分,直到所有的查询结果都显示完毕。
5.1 coordinator
中心的查询角色 接收查询请求、解析SQL 生成执行计划 任务调度 worker管理
coordinator进行是presto集群的master进程
5.2 worker
执行任务的节点
5.3 connector
presto以插件形式对数据存储层进行了抽象,它叫做连接器,不仅包含Hadoop相关组件的连接器还包括RDBMS连接器
具体访问哪个数据源是通过catalog 中的XXXX.properties文件中connector.name决定的
提取数据 负责实际执行查询计划。
5.4 discovery service
将coordinator和worker结合在一起服务;
worker节点启动后向discovery service服务注册
coordinator通过discovery service获取注册的worker节点
要想使用presto 还需要客户端 CLI客户端 or 应用客户端
六、 工作原理
6.1 presto中SQL运行过程
- 1、coordinator接到SQL后,通过SQL语法解析器把SQL语法解析变成一个抽象的语法树AST,只是进行语法解析如果有错误此环节暴露
- 2、语法符合SQL语法,会经过一个逻辑查询计划器组件,通过connector 查询metadata中schema 列名 列类型等,将之与抽象语法数对应起来,生成一个物理的语法树节点 如果有类型错误会在此步报错
- 3、如果通过,会得到一个逻辑的查询计划,将其分发到分布式的逻辑计划器里,进行分布式解析,最后转化为一个个task
- 4、在每个task里面,会将位置信息解析出来,交给执行的plan,由plan将task分给worker执行
6.2 presto执行过程
上图展示了Presto三个模块的动态交互过程,Client向Coordinator发起查询,Query创建后在Coordinator中经过Parser,Planner和Scheduler几个模块的依次处理后,下发给Worker执行,上图逻辑上是有一点错误,Worker执行完成的数据不是直接返回给Client,而是先经过Coordinator后,再经过Coordinator间接返回给Client,而Client与Worker之间没有交互。
七、 低延迟原理
- 基于内存的并行计算
- 流水式计算作业
- 本地化计算
Presto在选择Source任务计算节点的时候,对于每一个Split,按下面的策略选择一些minCandidates
优先选择与Split同一个Host的Worker节点
如果节点不够优先选择与Split同一个Rack的Worker节点
如果节点还不够随机选择其他Rack的节点- 动态编译执行计划
- GC控制
八、 容错
1、如果某个worker挂了,discovery service 会通知coordinator
2、对于query是没有容错的,一旦worker挂了,query就执行失败了,与其在这里容错不如直接执行
3、coordinator 和discovery service 的单点故障问题截止目前(2018年)还没有合适的解决方案,目前facebook的解决以cli重新提交查询来解决该问题。
九、Presto SQL on Everything
9.1 出现的名词解释
-
元数据:描述数据的数据
-
多租户系统(SaaS):多租户定义:多租户技术或称多重租赁技术,简称SaaS,是一种软件架构技术,是实现如何在多用户环境下(此处的多用户一般是面向企业用户)共用相同的系统或程序组件,并且可确保各用户间数据的隔离性。简单讲:在一台服务器上运行单个应用实例,它为多个租户(客户)提供服务。从定义中我们可以理解:多租户是一种架构,目的是为了让多用户环境下使用同一套程序,且保证用户间数据隔离。那么重点就很浅显易懂了,多租户的重点就是同一套程序下实现多用户数据的隔离。
- 通俗解释:我方为某OA系统运营商,服务在云上,供其他各类企业共同使用这一套系统,唯一区别在于数据的隔离性。
-
ETL:ETL是将业务系统的数据经过抽取(Extract)、清洗转换(Transform)之后加载(Load)到数据仓库的过程,目的是将企业中的分散、零乱、标准不统一的数据整合到一起,为企业的决策提供分析依据。
-
shuffle:洗牌,打乱数据顺序的意思。
-
谓词下推:基本思想即:将过滤表达式尽可能移动至靠近数据源的位置,以使真正执行时能直接跳过无关的数据。
-
ORC:ORC的全称是(Optimized Row Columnar),ORC文件格式是一种Hadoop生态圈中的列式存储格式