【数仓项目】沉舟侧畔千帆过-Presto

写在前面

数仓项目做的差不多了,有了很多表,很多数据,但是不能全都在终端查看吧?当然也可以用sqoop从hdfs导出到mysql或者其他数据库,但这里用了在即席查询方面更为优秀的Presto和Druid,本篇介绍Presto0.196,Druid放在下一篇。


Presto概述

Presto是一个开源的的分布式SQL查询引擎,数据量支持GB到PB字节,主要用于处理秒级查询的场景

PS:Presto可以解析SQL,但它不是标准的数据库,只是用来查询,并不能作为传统关系型数据库或者非关系型数据库的替代品

架构

Presto整体由一个Coordinator和多个worker组成
当运行一个Sql命令查找数据时会经历如下过程:
1.有客户端接收到查询命令,提交查询给Coordinator
2.Coordinator解析查询计划,然后分类发给不同的worker
3.worker负责在Catelog数据源执行任务和处理数据
4.一个Catelog包含Schema和Connector
5.Connector是适配器,用于presto连接不同数据源,类似于jdbc
6.Schema类似于数据源数据库,里面有表
7.任务完成后Coordinator负责从worker去结果并将结果返回给client
附官方架构图:

优缺点

优点

1.基于内存计算,减少了磁盘负担,计算更快
2.因为其worker机制能同时连接多个数据源进行查询,比如从hive中查询到某id再去mysql中将id对应数据取出来

缺点

presto的内存计算不是将数据读到内存中再计算,是根据场景,边读数据边计算,最后再清内存,所以连表查询时有可能产生大量临时数据,查询速度会很慢。

Presto的可视化工具yanagishima 18.0

读音:是日本姓,柳岛的意思,读音就按着罗马音读(别问我为什么去查,问就是学的东西不知道怎么读,难受)

个人观点:其使用十分方便,官方自带简直不能比,还可以格式化hql代码,太棒了~ 和官方的比嘛,一句歌词:如果真的是比可视化要强你好几倍
但是有一点吐槽:这个工具中写hql带分号会报错,一点也不人性化
使用截图如下(体验真是很好了):

优化

1.合理设置分区
与Hive类似,Presto会根据元数据信息读取分区数据,合理的分区能减少Presto数据读取量,提升查询性能。

2.使用压缩
数据压缩可以减少节点间数据传输对IO带宽压力,对于即席查询需要快速解压,建议采用Snappy压缩

3.使用列式存储
Presto对ORC文件读取做了特定优化,因此在Hive中创建Presto使用的表时,建议采用ORC格式存储。相对于Parquet,Presto对ORC支持更好。

4.只选择使用的字段(重要)
由于采用列式存储,选择需要的字段可加快字段的读取、减少数据量。避免采用*读取所有字段。比如:

1
SELECT time, user, host FROM tbl

5.优先使用分区字段进行过滤
对于有分区的表,where语句中优先使用分区字段进行过滤。acct_day是分区字段,visit_time是具体访问时间。

1
2
3
[GOOD]: SELECT time, user, host FROM tbl where acct_day=20171101

[BAD]: SELECT * FROM tbl where visit_time=20171101

6.Group By语句优化
合理安排Group by语句中字段顺序对性能有一定提升。将GroupBy语句中字段按照每个字段distinct数据多少进行降序排列。即先排序多的

1
2
3
[GOOD]: SELECT GROUP BY uid, gender

[BAD]: SELECT GROUP BY gender, uid

7.Order by时使用Limit
Order by需要扫描数据到单个worker节点进行排序,导致单个worker需要大量内存。如果是查询Top N或者Bottom N,使用limit可减少排序计算和内存压力。

1
2
3
[GOOD]: SELECT * FROM tbl ORDER BY time LIMIT 100

[BAD]: SELECT * FROM tbl ORDER BY time

8.使用Join语句时将大表放在左边(注意!这个和hive不一样,需分开讨论)
Presto中join的默认算法是broadcast join,即将join左边的表分割到多个worker,然后将join右边的表数据整个复制一份发送到每个worker进行计算。如果右边的表数据量太大,则可能会报内存溢出错误。

1
2
[GOOD] SELECT ... FROM large_table l join small_table s on l.id = s.id
[BAD] SELECT ... FROM small_table s join large_table l on l.id = s.id

使用时需注意

1.字段名引用
避免和关键字冲突:MySQL对字段加反引号、Presto对字段加双引号分割
当然,如果字段名称不是关键字,可以不加这个双引号。

2.时间函数
对于Timestamp,需要进行比较的时候,需要添加Timestamp关键字,而MySQL中对Timestamp可以直接进行比较。

1
2
3
4
5
/*MySQL的写法*/
SELECT t FROM a WHERE t > '2017-01-01 00:00:00';

/*Presto中的写法*/
SELECT t FROM a WHERE t > timestamp '2017-01-01 00:00:00';

3.不支持INSERT OVERWRITE语法
Presto中不支持insert overwrite语法,只能先delete,然后insert into。

4.PARQUET格式
Presto目前支持Parquet格式,支持查询,但不支持insert。

×

纯属好玩

扫码支持
谢谢你

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. 写在前面
    1. 1.1. Presto概述
    2. 1.2. 架构
    3. 1.3. 优缺点
      1. 1.3.1. 优点
      2. 1.3.2. 缺点
    4. 1.4. Presto的可视化工具yanagishima 18.0
    5. 1.5. 优化
      1. 1.5.1. 使用时需注意
,