0%

presto性能优秀原理和性能优化

[toc]

性能优秀的几个要点#

参考:知乎:Presto运行时浅析

1. 完全基于内存的并行计算#

不考虑存盘,因此很多操作都尽可能设计成在内存完成,几乎不考虑落盘的可能性。

2. 流水线计算#

只要Task中的算子从上游Task中可以获取到数据,便开始执行计算,计算产出的数据直接放入该Task对应的OutputBuffer中等待下游Task来访问,也就是说在执行非聚合算子的情况下,Client是可以源源不断的流式获取到计算结果,而不用等到所有数据都计算完成

3. 本地化计算#

Presto会根据元信息读取分区数据,提供的conectorApi可以适配不同的数据源做本地数据读取
合理的分区能减少Presto数据读取量,提升查询性能。
且可以提前本地计算,包括支持broadcast-join

4. 动态编译执行计划#

原始的逻辑执行计划,直接表示用户所期望的操作,未必是性能最优的,
逻辑执行计划fragment发送到机器上后,由结点树形式转写成operator list,根据逻辑代码动态编译生成字节码。动态生成字节码,主要是利用编译原理:

5. 小心使用内存和数据结构#

对于数据的计算是以Page为单位,
Page是由多个Block组成,每个Block为单一类型
例如Int Block, Long Block, Varchar Block等,其代表了Table中的某一列中的部分数据
因此数据可以被成为列数据
0fcd7788d61bdcbf62d73d3765b4ab778e7f7d95

6. 类BlinkDB的近似查询#

支持提供一个近似查询函数
例如approx_distinct() 函数比Count(distinct x)有大概2.3%的误差

近似查询概念:
如果数据库所存放的数据的数量十分庞大,要完成完整查询,则会需要花费较长的时间。如果我们使用近似查询技术,就可以以采样的方式,对均值的结果进行估计,以一定的精度损失,快速的获取对精确值的估计。这在某些场景下,会有一定的应用。不止是COUNT,SUM,AVG等常用的聚集估计方法都可以得到支持。除了简单的查询之外,近似查询还可以处理关联查询(join),嵌套查询,范围查询等复杂查询场景。

7. GC控制#


https://www.zhihu.com/question/461560750
https://www.sohu.com/a/310831715_115128
https://zhuanlan.zhihu.com/p/93711386

presto性能调优的几个方式#

Presto性能调优的五大技巧
Presto介绍与常用查询优化方法

提升并行度#

通过task.concurrency参数来设置join、aggregator等操作的并发度

但这个并行度是分多线程,还是用于控制多诘?

提升worker处理spilt的线程数#

如果工作器CPU利用率低并且所有线程都在使用中,则增加task.max-worker-threads

可以提高吞吐量,但是会导致堆空间使用率增加。将该值设置得太高可能会由于上下文切换而导致性能下降。(看起来并行度指的是节点并行度?)

worker中由于采用线程模型,因此Query对应算子的执行会从线程池中分配一个线程负责,而该线程对于Operator的执行时长为duration表示,超过duration所表示的时间,该线程就有机会切换执行其他query的算子,从而从粗粒度实现用户态CPU资源的分时调度,进而实现cpu层面的多租户。

增大每个worker上处理的split数#

node-scheduler.max-splits-per-node参数。

类似于一次性取多少spilt数据过来。

元数据有配置支持缓存,避免频繁获取元数据,加快加载速度。#

使用Join语句时将大表放在左边:#

Presto中join的默认算法是broadcast join,即将join左边的表分割到多个worker,然后将join右边的表数据整个复制一份发送到每个worker进行计算。

UNION ALL 代替 UNION :不用去重#