其他分享
首页 > 其他分享> > 【大数据】即席查询引擎Presto简单介绍

【大数据】即席查询引擎Presto简单介绍

作者:互联网

在文章OLTP和OLAP,数据库和数据仓库中我们了解了OLAP和OLTP以及数据库数据仓库的区别,本文主要最大数据下的即席查询引擎presto进行介绍。

在OLAP中,查询通常分为固化查询和即席查询:

Presto是由Facebook开源的一个分布式的SQL即席查询引擎,用于运行交互式分析查询。它可以处理从GB到PB的任何大小的查询。它旨在加速商业数据仓库查询处理。它可以扩大与Facebook相匹配的组织规模。为了解决hive查询慢产生。使用java编写,数据全部在内存中处理。原生集成了Hive、Hbase和关系型数据库,Presto背后所使用的执行模式与Hive有根本的不同,它没有使用MapReduce,大部分场景下比hive快一个数量级,其中的关键是所有的处理都在内存中完成。

Presto在一组机器上运行。Presto设置包括多个工作人员和协调员。Presto查询由其客户提交给协调器。然后,Presto协调器分析查询并创建其执行计划。稍后,处理过程将分配给工人。Presto支持在线数据查询,包括Hive,关系数据库(MySQL、Oracle)以及专有数据存储。一条Presto查询可以将多个数据源的数据进行合并,可以跨越整个组织进行分析。
在这里插入图片描述
Presto有两类服务器:Coordinator和Worker。

1)Coordinator
Coordinator服务器是用来解析语句,执行计划分析和管理Presto的Worker结点。Presto安装必须有一个Coordinator和多个Worker。如果用于开发环境和测试,则一个Presto实例可以同时担任这两个角色。
Coordinator跟踪每个Work的活动情况并协调查询语句的执行。Coordinator为每个查询建立模型,模型包含多个Stage,每个Stage再转为Task分发到不同的Worker上执行。
Coordinator与Worker、Client通信是通过REST API。
2)Worker
Worker是负责执行任务和处理数据。Worker从Connector获取数据。Worker之间会交换中间数据。Coordinator是负责从Worker获取结果并返回最终结果给Client。
当Worker启动时,会广播自己去发现 Coordinator,并告知 Coordinator它是可用,随时可以接受Task。
Worker与Coordinator、Worker通信是通过REST API。
3)数据源
Connector、Catelog、Schema和Table。这些是Presto特定的数据源。
(1)Connector
Connector是适配器,用于Presto和数据源(如Hive、RDBMS)的连接。你可以认为类似JDBC那样,但却是Presto的SPI的实现,使用标准的API来与不同的数据源交互。
Presto有几个内建Connector:JMX的Connector、System Connector(用于访问内建的System table)、Hive的Connector、TPCH(用于TPC-H基准数据)。还有很多第三方的Connector,所以Presto可以访问不同数据源的数据。
每个Catalog都有一个特定的Connector。如果你使用catelog配置文件,你会发现每个文件都必须包含connector.name属性,用于指定catelog管理器(创建特定的Connector使用)。一个或多个catelog用同样的connector是访问同样的数据库。例如,你有两个Hive集群。你可以在一个Presto集群上配置两个catelog,两个catelog都是用Hive Connector,从而达到可以查询两个Hive集群。
(2)Catelog
一个Catelog包含Schema和Connector。例如,你配置JMX的catelog,通过JXM Connector访问JXM信息。当你执行一条SQL语句时,可以同时运行在多个catelog。
Presto处理table时,是通过表的完全限定(fully-qualified)名来找到catelog。例如,一个表的权限定名是hive.test_data.test,则test是表名,test_data是schema,hive是catelog。
Catelog的定义文件是在Presto的配置目录中。
(3)Schema
Schema是用于组织table。把catelog好schema结合在一起来包含一组的表。当通过Presto访问hive或Mysq时,一个schema会同时转为hive和mysql的同等概念。
(4)Table
Table跟关系型的表定义一样,但数据和表的映射是交给Connector。

数据模型

1)Presto采取三层表结构:
Catalog:对应某一类数据源,例如Hive的数据,或MySql的数据
Schema:对应MySql中的数据库实例
Table:对应MySql中的表
2)Presto的存储单元包括:
Page:多行数据的集合,包含多个列的数据,内部仅提供逻辑行,实际以列式存储。
Block:一列数据,根据不同类型的数据,通常采取不同的编码方式,了解这些编码方式,有助于自己的存储系统对接presto。
3)不同类型的Block:
(1)Array类型Block,应用于固定宽度的类型,例如int,long,double。block由两部分组成:
boolean valueIsNull[]表示每一行是否有值。
T values[] 每一行的具体值。
(2)可变宽度的Block,应用于String类数据,由三部分信息组成
Slice:所有行的数据拼接起来的字符串。
int offsets[]:每一行数据的起始便宜位置。每一行的长度等于下一行的起始便宜减去当前行的起始便宜。
boolean valueIsNull[] 表示某一行是否有值。如果有某一行无值,那么这一行的便宜量等于上一行的偏移量。
(3)固定宽度的String类型的block,所有行的数据拼接成一长串Slice,每一行的长度固定。
(4)字典block:对于某些列,distinct值较少,适合使用字典保存。主要有两部分组成:
字典,可以是任意一种类型的block(甚至可以嵌套一个字典block),block中的每一行按照顺序排序编号。
int ids[]表示每一行数据对应的value在字典中的编号。在查找时,首先找到某一行的id,然后到字典中获取真实的值。

SQL运行过程:
1、coordinator接到SQL后,通过SQL语法解析器把SQL语法解析变成一个抽象的语法树AST,只是进行语法解析如果有错误此环节暴露。
2、语法符合SQL语法,会经过一个逻辑查询计划器组件,通过connector 查询metadata中schema 列名 列类型等,将之与抽象语法数对应起来,生成一个物理的语法树节点 如果有类型错误会在此步报错。
3、如果通过,会得到一个逻辑的查询计划,将其分发到分布式的逻辑计划器里,进行分布式解析,最后转化为一个个task。
4、在每个task里面,会将位置信息解析出来,交给执行的plan,由plan将task分给worker执行。
在这里插入图片描述

presto功能:

特点说明
多数据源目前presto可以支持MySQL、PostgreSQL、Cassandra、Hive、Kafaka、JMX等多种Connector,除此之外,京东商城改造之后的Presto也能够很好地支持Oracle、SQLServer,并且可以支持分库分表以及数据快速读取的功能
支持SQLPresto已经可以完全支持ANSI SQL,并提供了一个SQL Shell给用户,用户可以直接使用ANSI SQL进行数据查询和计算
扩展性Presto有很好的扩展性,开发人员可以很容易地开发出适用于自己特定数据源的Connector,并且可以使用SQL语句查询和分析自定义的Connector中的数据
混合计算在数据库中没重类型的数据源都对应于一种特定类型的Connector,用户可以根据业务需要在Presto中针对于一种类型的Connector配置一种或者多个Catalog,并查询其中的数据,用户可以混合多个Catalog进行join查询和计算
高性能经过Facebook和京东商城的测试,Presto的查询的平均性能是Hive的10倍以上
流水线由于Presto是基于PipeLine进行设计的,因此在进行海量数据处理的过程中,终端用户不用等到所有的数据都处理完毕才看到结果,儿使可以像自来水管道一样,一旦计算开始,就可以立即产生一部分的结果数据,并且结果数据会一部分接一部分地呈现在终端客户面前

Presto 核心数据结构:Slice、Page、Block

在 Presto 中,我们需要了解一些非常重要的数据结构,例如,Slice,Block 以及 Page,下面将介绍这些数据结构。

1、 Slice
从用户的角度来看,Slice 是一个对开发人员更友好的虚拟内存,它定义了一组 getter 和 setter 方法,因此我们可以像使用结构化数据一样使用内

Slice 常用来表示一个字符串:

// use it as utf8 encoded string
Slice slice = Slices.utf8Slice("hello");
Slice subSlice = SliceUtf8.substring(slice, 1, 2);

我们可以像使用字符串一样使用 Slice,Presto 为什么选择 Slice 而不是 String:

public interface BlockEncoding {
    /**
     * Read a block from the specified input.  The returned
     * block should begin at the specified position.
     */
    Block readBlock(SliceInput input);

    /**
     * Write the specified block to the specified output
     */
    void writeBlock(SliceOutput sliceOutput, Block block);
}

3、 Page
Page 由不同的 Block 组成:

public class Page {
    private final Block[] blocks;
    private final int positionCount;
    ...
}

除 Block 外,Page 还有另一个称为 Channel 的概念:每个 Block 都是该 Page 的 Channel,Block 的总数就是 Channel 数。因此,让我们在这里总结一下数据是如何结构化的,当要发送一些行时,Presto 这么做:将每一列放入单独的 Block 中、将这些 Block 放入一个 Page 中、发送 Page。
Page 是保存数据并在 Presto 物理执行算子之间传输的数据结构:上游算子通过 getOutput() 产生输出,下游算子通过 addInput() 方法获取输入,就像 Block 一样,Page 也需要序列化和反序列化,序列化发生在工作进程之间传输数据时。Page 进行序列化时,首先使用相应的 BlockEncoding 对 Block 进行编码。如果有压缩器,将尝试对编码的块数据进行压缩,如果压缩效果良好(编码率低于0.8),将使用压缩数据,否则使用未压缩的数据。编码后的块数据将与一些统计信息(压缩前后页面的字节大小)一起放入名为 SerializedPage 的类中。

总的来说,Slice 对应于虚拟内存,Block 代表列,Page 代表行组。

1、Kylin、druid、presto、impala四种即席查询对比
2、presto简介
3、Presto 核心数据结构:Slice、Page、Block

标签:Slice,Presto,查询,Connector,引擎,即席,Page,Block
来源: https://blog.csdn.net/dl962454/article/details/120615406