写在前面
数仓项目做的差不多了,有了很多表,很多数据,但是不能全都在终端查看吧?当然也可以用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]](/2020/03/25/【数仓项目】沉舟侧畔千帆过-Presto/1.png)
优缺点
优点
1.基于内存计算,减少了磁盘负担,计算更快
2.因为其worker机制能同时连接多个数据源进行查询,比如从hive中查询到某id再去mysql中将id对应数据取出来
缺点
presto的内存计算不是将数据读到内存中再计算,是根据场景,边读数据边计算,最后再清内存,所以连表查询时有可能产生大量临时数据,查询速度会很慢。
Presto的可视化工具yanagishima 18.0
读音:是日本姓,柳岛的意思,读音就按着罗马音读(别问我为什么去查,问就是学的东西不知道怎么读,难受)
个人观点:其使用十分方便,官方自带简直不能比,还可以格式化hql代码,太棒了~
和官方的比嘛,一句歌词:如果真的是比可视化要强你好几倍
但是有一点吐槽:这个工具中写hql带分号会报错,一点也不人性化
使用截图如下(体验真是很好了):
![[2]](/2020/03/25/【数仓项目】沉舟侧畔千帆过-Presto/2.png)
![[3]](/2020/03/25/【数仓项目】沉舟侧畔千帆过-Presto/3.png)
优化
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 | [GOOD]: SELECT time, user, host FROM tbl where acct_day=20171101 |
6.Group By语句优化
合理安排Group by语句中字段顺序对性能有一定提升。将GroupBy语句中字段按照每个字段distinct数据多少进行降序排列。即先排序多的
1 | [GOOD]: SELECT GROUP BY uid, gender |
7.Order by时使用Limit
Order by需要扫描数据到单个worker节点进行排序,导致单个worker需要大量内存。如果是查询Top N或者Bottom N,使用limit可减少排序计算和内存压力。
1 | [GOOD]: SELECT * FROM tbl ORDER BY time LIMIT 100 |
8.使用Join语句时将大表放在左边(注意!这个和hive不一样,需分开讨论)
Presto中join的默认算法是broadcast join,即将join左边的表分割到多个worker,然后将join右边的表数据整个复制一份发送到每个worker进行计算。如果右边的表数据量太大,则可能会报内存溢出错误。
1 | [GOOD] SELECT ... FROM large_table l join small_table s on l.id = s.id |
使用时需注意
1.字段名引用
避免和关键字冲突:MySQL对字段加反引号、Presto对字段加双引号分割
当然,如果字段名称不是关键字,可以不加这个双引号。
2.时间函数
对于Timestamp,需要进行比较的时候,需要添加Timestamp关键字,而MySQL中对Timestamp可以直接进行比较。
1 | /*MySQL的写法*/ |
3.不支持INSERT OVERWRITE语法
Presto中不支持insert overwrite语法,只能先delete,然后insert into。
4.PARQUET格式
Presto目前支持Parquet格式,支持查询,但不支持insert。