Presto 分布式SQL查询引擎及原理分析

Stella981
• 阅读 822

Presto 分布式SQL查询引擎及原理分析

​转载本文需注明出处:微信公众号EAWorld,违者必究。

前言:

Presto是由 Facebook 推出的一个基于Java开发的开源分布式SQL查询引擎,适用于交互式分析查询,数据量支持GB到PB字节。Presto本身并不存储数据,但是可以接入多种数据源,并且支持跨数据源的级联查询。

为何是SQL查询引擎?而不是数据库

和Oracle、MySQL、Hive等数据库相比,他们都具有存储数据和计算分析的能力。如MySQL具有 InnoDB存储引擎和有SQL的执行能力;如Hive 有多种数据类型、内外表(且这么叫)的管理能力,且能利用MR、TEZ执行HQL。而Presto并不直接管理数据,他只有计算的能力。

Presto 支持的数据源

常见的RDBMS都支持,如:Oracle、MySQL、PG等;

NoSQL:MongoDB、Redis、ElasticSearch 等;

大数据:Hive、HBase(第三方)、Kudu、Kafka 等;

Presto 支持从多种数据源获取数据来进行运算分析,一条SQL查询可以将多个数据源的数据进行合并分析。如如下SQL:a可以来源于MySQL,b可以来源于Hive。

select a.*,b.* from a join b on(a.id = b.id)

(左右滑动查看全部代码)

Presto 优势&特点

1.多数据源、混合计算支持:支持众多常见的数据源,并且可以进行混合计算分析;

2.大数据:完全的内存计算,支持的数据量完全取决于集群内存大小。他不像SparkSQL可以配置把溢出的数据持久化到磁盘,Presto是完完全全的内存计算;

3.高性能:低延迟高并发的内存计算引擎,相比Hive(无论MR、Tez、Spark执行引擎)、Impala 执行效率要高很多。根据Facebook和京东的测试报告,至少提升10倍以上;

4.支持ANSI SQL:这点不像Hive、SparkSQL都是以HQL为基础(方言),Presto是标准的SQL。用户可以使用标准SQL进行数据查询和分析计算;

5.扩展性:有众多 SPI 扩展点支持,开发人员可编写UDF、UDTF。甚至可以实现自定义的Connector,实现索引下推,借助外置的索引能力,实现特殊场景下的 MPP;

6.流水线:Presto 是基于PipeLine进行设计,在大量数据计算过程中,终端用户(Driver)无需等到所有数据计算完成才能看到结果。一旦开始计算就可立即产生一部分结果返回,后续的计算结果会以多个Page返回给终端用户(Driver)。

Presto 应用场景

1.实时计算:Presto 性能优越,实时查询工具上的重要选择。

2.Ad-Hoc查询:数据分析应用、Presto 根据特定条件的查询返回结果和生成报表。

3.ETL:因支持的数据源广泛、可用于不同数据库之间迁移,转换 和 完成 ETL 清洗的能力。

4.实时数据流分析:Presto-Kafka Connector 使用 SQL对Kafka的数据流进行清洗、分析。

5.作为MPP:Presto Connector 有非常好的扩展性,可进行扩展开发,可支持其他异构非SQL查询引擎转为SQL,支持索引下推。

数据模型

Presto 使用 Catalog、Schema和Table 这3层结构来管理数据。如图:

Presto 分布式SQL查询引擎及原理分析

1.Catalog:就是数据源。每个数据源连接都有一个名字,一个Catalog可以包含多个Schema,大家可以通过show catalogs 命令看到Presto已连接的所有数据源。

2.Schema:相当于一个数据库实例,一个Schema包含多张数据表。通过以下方式可列出catalog_name下的所有 Schema:

show schemas from 'catalog_name'

(左右滑动查看全部代码)

3.Table:数据表,与RDBMS上的数据库表意义相同。通过以下方式可查看'catalog_name.schema_name'下的所有表:

show tables from 'catalog_name.schema_name

(左右滑动查看全部代码)

在Presto中定位一张表,一般是catalog为根,例如:一张表的全称为 hive.test_data.test,标识hive(catalog)下的 test_data(schema)库中 test 表。

可以简理解为:数据源的类别.数据库.数据表。

可使用:show catalogs查看数据源;show schemas from hive查看数据库实例;show tables from default查看表。

切换当前使用的实例(在同一个数据源内切换无需指定catalog 前缀):use hive.default

Presto接入方式

Presto的接入方式有多种:presto-cli,pyhive,jdbc,SQLAlchemy 等,其中presto-cli 是Presto官方提供的,下面以presto-cli为例展开说明(自行到https://prestosql.io/download.html下载,presto-cli 应和 presto-server 版本相匹配),下载后把 presto-cli-${ver}-executable.jar 移动到 presto_home/bin 下:

mv presto-cli-${ver}-executable.jar presto

(左右滑动查看全部代码)

以连接hive数据源为例,在终端输入:

./presto --server host:8088 --catalog hive --schema default

(左右滑动查看全部代码)

先解释下各参数的含义:

  • --server 是presto服务地址;

  • --catalog 是默认使用哪个数据源,后面也可以切换;

  • --schema hive 数据源内的 default 库,可切换;

Presto 采用 Connector 对接第三方数据源,一个 Connector 便能提供一种新的 catalog

Presto中文使用手册:http://prestodb.jd.com/docs/current/index.html

Presto 整体架构

Presto 分布式SQL查询引擎及原理分析

1.Client:包括 prosto-cli 客户端以及 JDBC 驱动、ODBC 或 其他语言实现的Driver;

2.Discovery Service:是将 coordinator 和 worker 结合到一起的服务。Worker 节点启动后向Discovery Server 服务注册,Coordinator 从 Discovery Server 获得可以正常工作的 Worker 节点;

3.Coordinator:主要用于接收客户端提交的查询,解析查询语句,执行词法分析生成查询执行计划,并生成Stage 和 Task 进行调度;然后合并结果,把结果返回给客户端(Client);

4.Worker:主要负责与数据的读写交互以及执行查询计划;

Coordinator 和 Worker 可一起启动,这样小规模的集群或伪分布式可以节省一些资源。

 coordinator=true

(左右滑动查看全部代码)

单独启动 Coordinator:

coordinator=true

(左右滑动查看全部代码)

另一台节点启动 Worker:

coordinator=false

(左右滑动查看全部代码)

Presto SQL执行步骤

**1.**客户端通过 HTTP 发送一个查询语句给Presto集群的Coordinator;

**2.**Coordinator 接收到客户端传来的查询语句,对该语句进行解析、生成查询执行计划,并根据查询执行计划依次生成 SqlQueryExecution -> SqlStageExecution -> HttpRemoteTask;

**3.**Coordinator 将每个Task分发到所需要处理的数据所在的Worker上进行分析;

**4.**执行Source Stage 的 Task,这些Task通过Connector从数据源中读取所需要的数据;

**5.**处于下游的Stage中用的Task会读取上游的Stage产生的输出结果,并在该Stage的每个Task所在的Worker内存中进行后续的计算和处理;

**6.**Coordinator 从分发的Task之后,一直持续不断的从Single Stage 中的Task获得计算结果,并将结果写入到缓存中,直到所所有的计算结束;

**7.**Client 从提交查询后,就一直监听 Coordinator 中的本次查询结果集,立即输出。直到轮训到所有的结果都返回,本次查询结束;

实际上一个执行过程非常复杂,更过详细过程请见下期的《Presto查询执行过程和索引条件下推分析》文章。

为何 Presto 能有较高的查询性能?

**1.**得益于 YARN 调度的慢。YARN 的定位是一个通用的资源管理系统。但是无论是 Hive 采用 MR、TEZ 何种引擎,执行 SQL时,每个执行算子都在 Yarn Container 中运行,而 Yarn 拉起 Container 性能特别低(秒级)。这犹如应用程序在拉起进程和开启多线程一样。线程更轻量级,简单的运算开启线程的速度更快,加速更明显;而启用进程则要笨重的多,还容易受到操作系统限制。而 Presto 调度的确就是用了线程,而不是进程。

**2.**Presto 的Coordinator/Worker 架构更像 Spark Standalone 模式,只在两个进程和服务中完成。但是Spark更多侧重于 SparkRDD之间依赖关系,Stage失败线性恢复等功能导致有较大开销。Spark Input也直接依赖Hadoop InputFormat API,导致SparkSQL在运行时,并不能把 SQL 优化细节传导到 InputFormat。Presto 弃用 Hadoop InputFormat,但采用类似的数据分区技术,并且可以把 SQL 经过解析后,把Where 条件生成 TupleDomain 传递给 Connector。Connector 能根据字段元数据采用一定程度的索引下推,利用底层系统的索引能力,大大减少数据扫描区间和参与计算的数据量。

**3.**Presto 是完全基于内存的并行计算,他不像 Hive MR/TEZ 需要把中间数据写盘、Spark 需要把溢出的数据写盘,Presto 是完全假设数据能有效的放入内存。再者,得益于Presto流水线式的作业计算能力,在很多 SQL 执行时通过分析SQL的执行计划,能把立即展现的数据立即返回。这也是给用户一种很快的“假象”。但这种“假象”也是无可厚非的,我们即便是从一个结果中提取大量数据,也是遍历游标,等到我们遍历到那个位置,后续的结果数据已经源源不断的计算完成,并不影响我们获得结果。

Presto 发行版

Presto 到目前为止 Presto 有两大分支: PrestoDB 和 PrestoSQL。两个发行版都满足基本功能,只是在技术细节有细微差别。如底层通信方式、对部分文件的读取速度。总的来说,各有优劣。

PrestoDB: 根红苗正,有大厂支持;

PrestoSQL: Prestodb 之父的原班人马支持,社区更活跃;

在贸易战战火未消退的当下,也有很多企业关注License,两者都是 Apache V2 License。但是PrestoDB由 Facebook、Alibaba、Twitter等共同成立的基金会控制,PrestoSQL 是由新成立的Presto开源基金会管理,因此 PrestoSQL 也许更能符合国内企业选择。还有一个选择,Presto-JD(京东的分支版本)。

OLAP 众多,如何选型

OLAP 引擎,耳熟能详的当前有十几种之多,令人眼花缭乱。下图为第三方测试报告(来源:https://blog.csdn.net/weixin\_33724659/article/details/89548867)。

Presto 分布式SQL查询引擎及原理分析

通过编制综合对比分析表,这里采用5分为满分来比较,如下表:

Presto 分布式SQL查询引擎及原理分析

综合来看,Presto 是一款不可多得的、开源的 OLAP 分析引擎工具。

Presto 分布式SQL查询引擎及原理分析 关于作者:震秦,普元资深开发工程师。专注于大数据开发 8 年,擅长 Hadoop 生态内各工具的使用、优化和部分定制开发。曾参与国内多省市公安项目实施,负责大数据数仓设计、批处理和调度工具实现。

Presto 分布式SQL查询引擎及原理分析 关于EAWorld:微服务,DevOps,数据治理,移动架构原创技术分享。长按二维码关注!

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
3年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这