presto引擎业内通常用它来做即席查询,它基于内存计算效率确实快,不过它自身的任务优化参数比较杂,不同类型的catalog能用的参数不完全一样,在官网上倒是可以看到相关资料,配置文件中写的见https://prestodb.io/docs/current/admin/properties.html#
,会话参数见https://prestodb.io/docs/current/admin/properties-session.html
,但是看官网配置文档有个要注意的问题,汇总文档里面的配置不全,而且也没有表明配置的版本信息,有些参数比如会话参数hash_partition_count
,源码里面有,查询任务也正常识别,但是在参数说明里面就是没有罗列,只在官网其他文档里提到,有的也可能是官方计划后续版本要删除,但是无论哪种情况对使用历史版本的场景都是个不友好的事,所以日常收集还是有必要的
在设置参数的时候,要注意对于presto来讲,它也是stage分隔任务的执行计划,并在不同的执行节点上,但是和spark这些基于mapreduce-shuffle引擎不一样的是,这些stage是并行的,不是顺序执行。因为presto它采用的是MPP架构,而不是MapReduce,数据交换的机制严格来讲不叫shuffle,而是Exchange
一个sql对于presto来将就是一个查询任务(query),在你提交查询任务时,你会发现会话参数对于presto讲也是一个查询任务,而不是像spark这些引擎一样包含在AM的配置里面,通俗的讲就是在这一个会话提交的生命周期内,更改了集群策略,只生效在一次连接中的任务而已。而一个查询任务不同阶段的执行计划(stage)中包含了多个最小执行单元任务(task),每个任务都有自己的最小调度单元(drivers),可以理解为是线程数,这点和spark这些引擎也不太一样,spark或者yarn是执行器executor或者container持有资源来跑任务,而presto没执行容器这个概念
在下列列出的参数中,并不是所有,只有我在工作中使用较多的,且截止0.272为止
,这些参数使用上都是没问题的,在往后的版本就需要你自己测一下了。除了这些presto还有很多使用权重不高的配置,比如在0.182版本开始,presto提供了任务执行时,用于聚合处理的最大内存,还有在0.254版本开始提供了显示的开启溢出配置,通过experimental.query-limit-spill-enabled配置
或者query_limit_spill_enabled会话属性
开启溢出能力,而之前的版本只有experimental.aggregation-operator-unspill-memory-limit配置
或者aggregation_operator_unspill_memory_limit会话属性
设置溢出策略,效果不明显,同时虽然可选的溢出策略有PER_TASK_MEMORY_THRESHOLD:默认值按照任务自身衡量任务是否溢出
、TOTAL_MEMORY_THRESHOLD:按照集群内存总和来衡量,使得使用内存最大的任务溢出
、NONE:不溢出
、在0.220左右还出现过一个LIMIT策略具体名字记不太清了,但是只存在了一段时间就被删掉了
,但是有资源组和集群级别的资源监控可以让任务触发到内存上限之后就可以歇菜了,一个会溢出数据的任务常常伴随着较大的不合理性。在0.256版本之后还可以单独控制去重操作是否允许溢出的experimental.distinct-aggregation-spill-enabled 配置属性
和distinct_aggregation_spill_enabled 会话属性
,以及排序操作是否允许溢出的experimental.order-by-aggregation-spill-enabled 配置属性
和order_by_aggregation_spill_enabled 会话属性
需要明白的是,这里罗列的参数除了几个特殊的,其他的主要是为了任务级别的优化,所以通常优先记录会话级别参数,但是一般情况下presto提供了对应的配置文件内容,你可以在开头的官网的会话参数链接里面找到对应的超链接
还要留意的是,所有presto配置的值类型需要明确,且单位完整。比如spark在配置一些字节大小单位的时候MB
可以简写为M
,但是在presto中就会报错,而且会话参数使用时,只要不是数字或者布尔类型的都要用双单引号包裹,而写在配置文件里面的就不需要
**1、**0.204版本开始,presto对hive的数据可以用覆盖写,其他值可以用append和error
bash
set session <hive-catalog>.insert_existing_partitions_behavior = 'overwrite';
注意
从0.123版本开始,可以对hive数据执行insert 和 delete操作,但0.123版本下insert还不能控制覆盖和追加,delete操作也只能删除分区字段类型为字符串的分区表,直到0.126版本开始delete才可以删除非字符串的分区数据,这一点了解一下即可
**2、**0.191版本开始,添加了运行时生成文件大小的策略
bash
set session scale_writers = true;
-- scale_writers = true时,文件大小超过writer_min_size的阈值才生产下一个文件
set session writer_min_size = '32MB';
**3、**在0.234版本中加入了writer扩展功能,通过上游stage任务的缓冲区使用情况,来自动调整数据落盘的并行度
bash
set session optimized_scale_writer_producer_buffer = true;
**4、**从0.102版本开始,可以指定任务运行时写入执行器的并行度,需要注意的是这个配置和writer扩展功能是互斥的。对其他所有insert非分区表类型任务有明显效果,这个配置在0.102之前的版本中只能通过改配置文件的task.writer-count
实现,在设置时个人建议优先使用scale_writers和writer扩展功能
,如果你实在想用指定的方式,需要注意这个配置必须用偶数值
bash
set session task_writer_count = 2
到了0.227版本才添加了针对写入分区表的执行器数量控制,不过可以统一使用task_writer_count
bash
set session task_partitioned_writer_count = 2
**5、**presto执行任务过程中,任务按照执行计划,内部的具体task操作被分步在固定数量的节点上,这点和spark哪些一样
而从0.55版本开始,参与的执行节点数有多少,则由分区系数也就是query.initial-hash-partitions
影响。或者通俗讲presto在用哈希决定stage内的task要生成多少个时的常数因子,因子越大,生成的task越多,所需要的节点数也就越多,同样使用资源也就越多,当然这个是初始状态,后续执行presto会自己调整,可以理解为spark动态扩展资源类似的策略,presto会尽量让stage的task数靠近这个因子数
修改时通过更改etc/config.properties
文件,来修改默认的分区系数,0.55版本开始生效,默认8,2xx后新版本为100
bash
query.initial-hash-partitions=8
注意
,最终生效的取值是在给定配置和集群可用节点数中取最小值,这是presto为了防止分区系数过大给集群造成不必要的风险,对于单个任务来讲,理想状态下,分区系数应当小于等于节点数,这样集群中所有的任务才能尽量的负载均衡。
从0.101版本开始,除了写在配置文件中的初始哈希分区系数之外,还可以通过会话来指定任务执行中的哈希分区
bash
SET SESSION hash_partition_count=10
6、新版本废弃presto提供了一个全局的列文件阅读器,在抽取hive数据时,提高读取性能,在0.6x版本提出了概念,随后在0.79(该版本时此功能是实验性的)和0.80版本推出,不过这个配置在后期版本推出不同特殊文件类型的处理优化就失效了,放在这里是为了让大家知道最开始presto是统一优化的
全局可用在hive的catalog文件
配置
bash
hive.optimized-reader.enabled=true
或者任务会话级别
bash
SET SESSION <hive-catalog>.optimized_reader_enabled = true;
**7、**presto多数应用在即席查询中的引擎,而不用来持久的运行大任务,但是在0.80版本开始支持内部添加了独立于其他配置的单独队列,可以用来跑大任务,但是在0.80版本中是实验性的
使用时需要在etc/config.properties
文件中配置如下内容
bash
# 控制同时运行的"Big Query"数量
experimental.max-concurrent-big-queries=5
# 控制等待队列中的"Big Query"数量
experimental.max-queued-big-queries=10
# 设置"Big Query"的初始哈希分区数
experimental.big-query-initial-hash-partitions=100
# 设置"Big Query"每个任务的最大内存
experimental.big-query-max-task-memory=4GB
随后在大任务的会话属性中携带标识
bash
SET SESSION experimental_big_query = true;
presto最早的正式版本是0.8X,刚开始的时候是没有完整的集群资源管理组件的,所以对于大查询就临时搞了上面的配置。而在0.103版本,推出了一个全新的资源管理器,用来监控并统一管理集群资源,防止集群过载。0.109版本开始上面的大任务查询能力废弃,所有的相关配置也都被删掉了,所以上面的大查询配置更多的是一个了解,知道曾经有怎么个东西就行。
在未配置资源组时,presto可以直接使用这个全新的资源管理器,当然资源组提供了更细致的把控能力,只不过低版本的时候资源组能力不健全而已,到了0.153版本开始,presto才可以正常配置资源组。
改动它需要在在config.properties中操作
。注意
如果你用的是0.116以后的版本,这个内存管理器始终保持开启,没有启停开关
properties
# 启用集群内存管理器,0.116以后这个配置没有了,内存管理器始终保持开启
experimental.cluster-memory-manager-enabled=true
0.116版本,为这个资源管理器新增了终止任务的能力,当集群接近内存上限时终止一个内存使用最多的任务释放内存资源,至于内存的上限是presto自己有判断逻辑。但是按照我的使用经验来讲,如果你用的版本能够直接配置资源组,那你正常使用资源组就行了,这个资源管理器它能够起到的作用微乎其微,甚至很多时候感觉不到它的存在,通常集群负载率高的时候,等不到终止任务策略的生效,任务节点上的task就挂了,总之在集群出问题之前触发的概率低到令人发指
bash
# 启用低内存终止器
query.low-memory-killer.enabled=true
# 终止器的生效前的延迟时间为 2 分钟
query.low-memory-killer.delay=2m
注意!!!!!!启用内存终止器在0.191版本之后的配置变了
bash
query.low-memory-killer.enabled 《--这个弃用了
query.low-memory-killer.policy 《--用这个了,并且可选的值有三个
none #不启用终止器
total-reservation #终止集群中内存使用最多的一个任务
total-reservation-on-blocked-nodes #终止在高压节点上任然调用大量内存的一个任务
**8、**如果你能保证所有的hive表分区字段是字符串类型,则0.90版本开始,可以在hive的catalog配置文件中使用有优化的读取策略,节省一些io的消耗。说白了就是presto会跳过分区字段类型的检查和规范读取,直接用字符串的方式识别。这个配置在0.90版本之前是没有提供的,就导致如果你的分区字段类型不是字符串,presto用优化策略读取会有忽略数据的可能,实际使用一般用false。
bash
#默认 false 禁止用优化读取策略
hive.assume-canonical-partition-keys=true
**9、**presto默认使用编译后的字节码来识别sql,这能够保证高效的执行sql,但偶尔会发生表达式无法转换成字节码。于是0.90版本开始,提供了一个参数,发生无法转换字节码的时候,让presto用解析器识别sql,这种任务执行会慢很多,但是不会直接报错。直到0.195版本相应的问题被解决,这个配置也被删除了
在etc/config.properties
文件中配置如下内容,这个配置并没有提供对应的会话参数,本身是用于调试或测试集群的一个参数,使用0.195以后的版本限于了解就行
bash
#false指始终不使用解析器,遇到问题直接报错
compiler.interpreter-enabled=true
**10、**从0.94版本开始,可以指定每个task任务最小可持有线程数,注意这个配置不能小于3,不然presto很容易出现资源锁
bash
task.min-drivers=8
到了0.205版本开始,提供了一对新的配置,用来指定任务在有足够工作要做的情况下,并发线程数的最小最大数量,0.205+的版本建议用这个,因为上面的配置直接指定的话,不可能对所有任务都是有益的
bash
#最小一般用 1 就行
task.min-drivers-per-task=1
task.max-drivers-per-task=16
**11、**从0.100版本开始,在presto的配置文件中,可以控制单个执行节点可持有的最大线程数,合理的设置可以保证任务的稳定,在之前的版本中使用的是task.shard.max-threads
在etc/config.properties
中修改如下配置,它的默认值是所在节点的CPU数*2
,可以执行一个常数,或者使用1.5C
这种表达式,指核数的1.5倍,presto解析时会四舍五入取整数
bash
task.max-worker-threads=64
**12、**在spark中处理orc数据有强制解析的能力,而presto在0.137开始也支持了一样的能力,达到用具体列名字在文件中找列数据的能力,需要你在hive的catalog文件中启用。
不过,orc和presto的这个能力,通常是用来弥补presto虽然完全使用hive的元数据,但是受到hive修改表元数据或分区元数据时,是否级联或是否使用了replace,而导致的分区字段顺序和表元数据顺序不一致的问题,因为hive自身在不一致的情况下是参考表级别元数据的字段顺序在分区级别元数据对应的列中取一个,错了就错了,当然这主要是因为hive新增或者修改字段元数据是不改变已有字段顺序的,除非用户手动用replace语句修改。因此如果你可以保证顺序不变,就不要用这个配置
bash
hive.orc.use-column-names=true
**13、**从0.101版本开始,hive的Parquet文件数据使用按顺序读取的方式,如果需要按字段直接访问,也就是和orc强制解析一样的能力,需要在hive的catalog文件中启用
bash
hive.parquet.use-column-names=true
**14、**从0.101版本开始,考虑到hive数据由于spark这些第三方引擎处理时会有目录,添加了递归目录的支持,在hive的catalog配置文件中启用即可,但是这个能力谨慎使用,因为不是所有的目录都是有效数据,可能只是任务失败没有删除,尤其是spark处理过的数据
bash
hive.recursive-directories=true
**15、**在0.103版本中,加入了中间结果聚合时的多线程控制,提高聚合效率,因为之前版本都是单线程
bash
SET SESSION task_default_concurrency
SET SESSION task_join_concurrency
SET SESSION task_hash_build_concurrency
SET SESSION task_aggregation_concurrency
0.147版本开始,presto用一个统一的参考值来自动决定上面的4个配置,提供的新会话参数为
bash
SET SESSION task_concurrency=16
或者在config文件中配置
bash
task.concurrency=16
**16、**presto在读取hive数据时,可以控制拆分数据块的大小,需要在hive的catalog文件中配置
bash
#对于非特殊格式,可以通用下面的4项
hive.max-split-size:控制Hive表拆分的最大大小。增加此值可以减少拆分数量,从而减少查询开销。
hive.max-initial-split-size:控制初始拆分的最大大小。增加此值可以加快查询启动速度。
hive.max-outstanding-splits:控制同时处理的最大拆分数量。增加此值可以提高并行度,但也会增加内存使用量。
hive.max-split-iterator-threads:控制用于生成拆分的线程数。增加此值可以加快拆分生成速度。
#orc这个类型配置是单独的
hive.orc.max-buffer-size:控制ORC文件读取器的最大缓冲区大小。增加此值可以提高读取性能,但也会增加内存使用量。
hive.orc.stream-buffer-size:控制ORC文件读取器的流缓冲区大小。增加此值可以提高读取性能,但也会增加内存使用量。
hive.orc.max-read-block-size:控制ORC文件读取器的最大块大小。增加此值可以提高读取性能,但也会增加内存使用量。
#常用的文件存储类型还有一个Parquet,在presto中提供了一个单独的读取器,下一条单独说
presto在0.272版本中,加入了对hive数据拆分能力的启停配置
bash
SET SESSION file_splittable=true
或者写在hive的catalog文件中
hive.file-splittable=true
**17、**在0.138版本开始,presot对对于hive的Parquet数据新增了一个阅读器,提供了更好的读取能力,注意
这个配置在0.213版本删掉了,并不是这个新的阅读器有什么问题,而是删除了旧的读取器,直接使用这个新的了
bash
SET SESSION <hive-catalog>.parquet_optimized_reader_enabled=true
或者写在hive的catalog文件中
bash
hive.parquet-optimized-reader.enabled=true
到了0.227版本,添加了读取parquet数据块最大值的限制
bash
SET SESSION parquet_max_read_block_size='16MB'
或者写在hive-catalog中
hive.parquet.max-read-block-size=16MB
到了0.138版本开始,presto对hive的Parquet数据提供了predicate push down
能力,直译过来叫谓词下推,其实就是将可行的过滤条件下放到抽取文件这一层,而不是文件加载到内存中之后跑任务的时候过滤,来减少计算过程中的数据IO消耗。注意
这个能力在0.213版本开始始终启用,对应的配置也不允许配置更改了
0.213版本之前可以使用会话属性开启
bash
SET SESSION <hive-catalog>.parquet_predicate_pushdown_enabled=true
或者写在hive的catalog中
bash
hive.parquet-predicate-pushdown.enabled=true
**18、**0.153版本开始,对于hive数据的orc也有了predicate push down
能力,通过会话属性开启
c
SET SESSION orc_bloom_filters_enabled=true
或者写在hive的catalog文件中
bash
hive.orc.bloom-filters.enabled=true
**19、**0.107版本开始添加了会话级别的任务可用最大内存,但是不能超过配置文件中的限制,因此用的不多
bash
SET SESSION query_max_memory
**20、**0.109版本,支持数据落盘前重新进行哈希分区,也就是写如的分区下的文件尽量平衡,避免数据倾斜,通过修改etc/config.properties
可以起停
bash
redistribute-writes=true
或者写会话参数也行
bash
SET SESSION redistribute_writes=true
需要知道的是,在0.232版本添加过一个没有太大实际意义,如重新分区可行,则强制分区的会话参数,主要是用来解决数据写入时发生了跨分区问题,开启后会严格按照分区写入数据,但是一般不会出现分区错乱问题,我本人在工作中没有使用过,只是官方文档中有提到这个配置,在后期的版本中已经删除
bash
SET SESSION use_exact_partitioning=true
**21、**0.112版本加入了对hive的orc数据读取时的域压缩,就是指针对or或者in语句,元祖域在多少范围内不压缩,个人理解就是你写的条件查多少个之内,presto不对把单个的扫描,优化为扫描一个范围后在单独找,配置时需要在hive的catalog文件中操作
bash
hive.domain-compaction-threshold=20
**22、**0.202版本中加入了,读取hive-orc数据时视为小条带的阈值,这使得presto决定是否一次读取多个条带,来提升读取性能
bash
hive.orc.tiny-stripe-threshold=20MB
或者
SET SESSION orc_tiny_stripe_threshold=20MB
**23、**从0.112版本开始,不要直接用presto对hive执行create table
语句,因为这个版本开始直接create hive表在元数据上会不完整,导致hive表无法访问,注意create table as
不受影响
**24、**从0.116版本开始,可以对查询指定最大的执行时间,注意
这个配置和资源组的最大执行时间限制是互斥的,资源组优先级高
在config.properties中全局配置
bash
# 设置查询的最大运行时间为 1 小时
query.max-run-time=1h
或者使用会话配置
bash
SET SESSION query_max_run_time = '30m';
**25、**从0.116版本开始,presto内部默认对哈希的使用做优化来减少生成开销,并且了优化join时的操作,可以在config文件中启停它们。
bash
# 启用哈希生成策略的优化
optimizer.optimize-hash-generation=true
# true 讲join涉及的数据分布给多节点并行处理,false 将小表广播
distributed-joins-enabled=true
或者用会话参数
bash
SET SESSION optimize_hash_generation=true
SET SESSION distributed_joins=true
注意
0.123版本之前不要关闭哈希优化,查询会由于哈希生成的一个bug失败。在0.139版本之前不要启用join数据分布执行优化,会有失败的情况
0.207版本开始,presto对于join优化提出了新的优化配置,并且不再推荐直接使用上面的distributed-joins-enabled
配置项,新的配置项如下
bash
新的会话属性:join_distribution_type
新的配置属性:join-distribution-type
新的配置项有三个可选值,但是为了简化开发,presto任然允许你携带旧参数,会自动转化为对应的配置值
bash
PARTITIONED:等价于distributed_joins=true,按照join条件字段分区后多节点并行
BROADCAST:等价于distributed_joins=false,将小表广播出去
AUTOMATIC:根据执行计划,自动选择 PARTITIONED 或者 BROADCAST
在0.238版本开始,对于小表的广播presto可以限制可用资源的内存大小
bash
SET SESSION query_max_broadcast_memory='1GB'
query.max-broadcast-memory=1GB
在0.289开始,提供了一种智能广播策略,presto会自己决定join时哪些数据可以广播,不需要你在额外的手动配置
bash
SET SESSION confidence_based_broadcast=true
或者写在config文件中
optimizer.confidence-based-broadcast=true
**26、**0.241版本开始,presto通过添加动态过滤和桶修剪支持,提高广播或串联的查询性能,需要时在config文件中配置
bash
experimental.enable-dynamic-filtering=true
或者使用会话参数
SET SESSION enable_dynamic_filtering=true
**27、**0.191版本开始,如果你的任务所抽取的数据,在分布式join中的分布依据相同,比如hive表的分区键值相同,则可以使得Presto 尝试利用表数据的分布信息,将 Join 操作的数据分发到相同的 Worker 节点上执行,从而减少数据移动和网络传输,提升查询性能,个人建议0.197以后的版本再考虑用这个参数
bash
SET SESSION colocated_join=true
SET SESSION concurrent_lifespans_per_task=1
在0.205之前要用colocated_join,就必须同时携带concurrent_lifespans_per_task,但是在之后的版本中,concurrent-lifespans-per-task
默认值是1,它是指一个task中可以并行处理几个presto对文件生命周期的抽象计划,通俗的理解为同时对几个数据块跑数
**28、**0.177版本开始,提供了一些join性能和聚合性能的优化,可以通过会话属性打开
bash
SET SESSION push_aggregation_through_join=true
SET SESSION push_partial_aggregation_through_join=true
**29、**从0.124版本开始,presto实验行的支持了MR和Spark类似的中间聚合,来减少大内存任务数据交换量
bash
SET SESSION task_intermediate_aggregation=true
或者在配置文件中全局配置
bash
optimizer.use-intermediate-aggregations=true
在0.147版本这个实验性质的能力删掉了。提供了全面的磁盘数据交换能力,从使用上来讲,截止本文书写时间2025-03月,要求存在一个用来做数据交换的hive-catalog,在将来可能会支持其他的,使用上只需要携带下面的会话参数即可
bash
#控制数据磁盘交换的行为,可选值:NONE(禁止)、ALL(对所有的数据交换做物理交换)、AUTOMATIC(自适应,但是一般不用)
SET SESSION exchange_materialization_strategy='ALL';
#这里是你的hive-catalog
SET SESSION partitioning_provider_catalog='hive';
#当你开启了数据磁盘交换,hash_partition_count就不再和集群节点取最小值,而是跟随你的设置来,并且官方建议设置为presto节点数的5-10倍
SET SESSION hash_partition_count = 4096;
0.222版本开始,物理数据交换,可以指定任务计划的并行度,适当的提升即可
bash
max-concurrent-materializations=10
SET SESSION max_concurrent_materializations=10
**30、**从0.126版本开始,可以使得所有task之间共享数据的索引,说白了就是缓存了元数据信息,比如hive的数据存储路径这种,这在查询速度的优化上起到关键作用
在config文件中配置
bash
task.share-index-loading=true
或者会话属性
bash
SET SESSION task_share_index_loading=true
**31、**0.126版本加入了一个特殊的配置hive.immutable-partitions
,默认值是false
,可以将hive的分区数据视为不变的,使得presto缓存数据表分区元数据,包括列、文件大小、类型等等,好处是下一次读取不需要在元数据识别上额外开销,坏处是会影响更新后数据的读取,不过不是每次都影响,是个偶发的时间
可以在hive的catalog中配置
bash
hive.immutable-partitions=true
到了0.235版本,presto支持直接指定缓存哪些表的元数据信息于文件中
bash
# *代表缓存所有表,多个表用逗号隔开
hive.file-status-cache-tables=*
#缓存的实效时间
hive.file-status-cache-expire-time=1d
如果你要使用这个配置,遇到元数据没更新的相关问题,可以调用presto的储存过程,这个存储过程调用前提,必须是连接presto后指定了默认的catalog为hive,比如./prestocli --server node3:8881 --catalog hive
,在sql中写catalog不生效
bash
# 同步元数据到缓存中,FULL 是同步模式,不用改
CALL system.sync_partition_metadata(
schema_name => 'default',
table_name => 'a',
mode => 'FULL'
);
**32、**在0.129版本开始,presto尝试支持了hive的retention_days表属性,但是然并卵,因为它照常调用hive内部的支持,但hive自身表失效时间是一个没有使用的功能,所以在0.137的时候presto又把这个参数给删掉了,这一点了解就行
**33、**在0.130版本开始,presto对于过滤执行、列存储数据、可用的字典编码、列映射上提供了查询性能的改进
可以在config文件中修改
bash
optimizer.columnar-processing-dictionary=true
也可以用会话参数
bash
SET SESSION columnar_processing_dictionary=true
0.149版本以后这个配置被重置为optimizer.processing-optimization
配置,或者使用processing_optimization
会话属性,可选配置值为disabled
、 columnar
、columnar_dictionary
,而0.174版本开始这些配置就都被删掉了,除了字典编码优化之外,其他的都不再使用了,所以如果你使用的是130-173的版本,可以用一用这个参数
而字典编码优化能力被单独保留了下来,你可以通过dictionary_aggregation
会话参数开启,这里的字典编码指的是presto会自己判断,在合适的实际将数据组成类似于我们数据处理中常用的代码值那样的字典数据,来优化执行效率
bash
SET SESSION dictionary_aggregation=true
或者写在config文件中
optimizer.dictionary-aggregation=true
**34、**在0.132版本开始,presto添加了一个参数,可以让集群在内存不足的时候情况下,任然调度任务,但是集群负载高的时候容易触发OOM,以及增加集群风险
bash
SET SESSION resource_overcommit=true
**35、**0.138版本开始,可以控制任务执行初始状态下每个节点负责的数据分片数量,以及任务执行过程中自动调整的时间间隔
写在config文件中
bash
task.initial-splits-per-node=32
task.split-concurrency-adjustment-interval=100ms
或者使用会话参数
bash
SET SESSION initial_splits_per_node=32
SET SESSION split_concurrency_adjustment_interval='100ms'
**36、**0.142版本开始,presto跑任务提供了读取元数据上的优化,来提高效率,但是个人不建议用,因为如果操作的数据是空的,比如只有hive数据的物理路径被删除了,这个配置可能影响任务结果,而且在0.279版本修复了使用这个参数,对分区列聚合以及行字段元数据读取上的bug,bug导致查询结果错误,总之不建议轻易使用,知道有这么个配置当作逼不得已用的一个参数就行,用也在0.279之后用
bash
SET SESSION optimize_metadata_queries=true
**36、**0.142版本开始,presto写hive数据会使用压缩,默认是gzip,可以在hive的catalog中更改
bash
hive.compression-codec=GZIP
注意,0.220版本后,可以通过会话属性compression_codec
指定,可选择NONE、SNAPPY和GZIP
**37、**0.143版本开始,添加了对查询可用最大cputime的限制,需要在config中设置,不过一般会商用场景下会使用资源组限制查询时间
bash
query.max-cpu-time=1h
**38、**0.147版本开始,presto支持对有长度字符串数据源控制,比如mysql这种关系数据库的varchar类型,你可用通过varchar(n)
来实现
0.153版本开始,支持了real类型来操作hive的float单精度浮点数,并支持了char(x)
,和上面的varchar(n)
一样
**39、**0.156版本开始,presto针对聚合项很多的任务提供了一种优化,底层执行会尝试将多个共性的任务合并成一个统一的执行计划,但是个人建议不要在0.200版本之前用它,因为早先用170左右的版本时,当聚合数据的预期结果是0,发现实际结果可能会是错误的NULL
,而不是预期的0
,后面使用0.272的时候没有发现这个bug问题复现
bash
SET SESSION optimize_mixed_distinct_aggregations=true
或者写在config文件中
bash
optimizer.optimize-mixed-distinct-aggregations=true
到了0.281版本,presto对同节点上的多个相似聚合也提供了合并优化的能力
bash
SET SESSION merge_duplicate_aggregations=true
**40、**0.159版本开始,presto可以在hive的catalog文件中限制任务最大扫描的分区数
bash
hive.max-partitions-per-scan=100000
**41、**0.165版本开始,presto支持数据处理过程中,不同节点交换数据是否压缩,这里的交换指的就是最开头说的MPP架构中的exchange,可以在config文件中配置
bash
exchange.compression-enabled=true
**42、**0.175版本开始,presto支持了非分组shuffer时的中间聚合
bash
SET SESSION enable_intermediate_aggregations=true
**51、**0.188版本开始,presto提供了对gc的优化,在任务执行中陆续压缩处理中间数据,而不是到了一个临界点一次性压缩,这个优化能力需要在config文件中配置
bash
pages-index.eager-compaction-enabled=true
**43、**0.190版本开始,对于十进制的数字,可以选择让presto用double类型处理,而不是DECIMAL,所以当你的任务中浮点数允许舍去精度的话可以考虑采用,这个是生效在拉数据阶段,所以开启后cast成decimal(x, y)
虽然也可以,但是要分实际使用情况而定
在config文件中全局配置
bash
parse-decimal-literals-as-double=true
或者使用会话级别参数
bash
# true是可以解析成double
SET SESSION parse_decimal_literals_as_double = true;
**44、**0.190版本开始,对于hive数据,可以限制等待处理数据切片的总大小,使得集群稳定行更强,当拉取的数据切片到达了上限后会暂停拉取,直到已拉取的数据切片处理完成,这依赖于presto主节点对hive元数据的处理,如果设置不合理那么在任务的耗时和成功率上可能会有一些影响
在hive的catalog中配置
bash
hive.max-outstanding-splits-size=512MB
**45、**0.198版本开始,可以限制任务节点上不同task之间的本地数据交换缓冲区大小
bash
task.max-local-exchange-buffer-size=32MB
**46、**0.198版本开始,presto对去重关键字提供了一种实验性的优化,用来解决高基数场景
bash
optimizer.use-mark-distinct=true
或者
SET SESSION use_mark_distinct=true
在0.234版本之后,去掉了实现性质,并支持强制mark-distinct去重策略
bash
SET SESSION use_stream_exchange_for_mark_distinct=true
或者写在配置中
query.use-streaming-exchange-for-mark-distinct=true
**47、**0.208版本中加入了任务stage数量的限制,一般单任务可承受12T抽取数据-4T任务内存
的生产集群,通常在200-250之间,通过config文件修改
bash
query.max-stage-count=100
或者会话属性,注意不要轻易改会话属性,因为它可以超过配置文件中的限制
bash
SET SESSION query_max_stage_count=100
在0.217版本中加入了一个配套使用的config配置,当stage到达指定阈值后,会抛出一个TOO_MANY_STAGES
警告
bash
query.stage-count-warning-threshold=50
在0.221版本中加入了一个stage中task的上限,这个和最上面的哈希分区基数是互斥的
bash
stage.max-tasks-per-stage=20
SET SESSION max_tasks_per_stage=20
**48、**0.207版本开始,presto对join的连接计划提供了一种优化手段
bash
SET SESSION join_reordering_strategy
或者配置文件中写死
optimizer.join-reordering-strategy
可选的值有三种
bash
NONE:不对任务的join计划做任何变动
ELIMINATE_CROSS_JOINS:会优化掉不必要的连接,比如重复的交叉连接
AUTOMATIC:根具给定的条件自动整理并执行最优解
在0.207版本之前,没有AUTOMATIC
策略,用的是reorder_joins会话属性 或者 reorder-joins配置
来控制优化方法,为了简化变更难度,和分布式join优化配置项一样,presto没有物理删除这两个旧的配置,当reorder_joins=true相当于ELIMINATE_CROSS_JOINS,false相当于NONE
需要注意的是,如果你使用了AUTOMATIC
,则必须限制自动优化join条件时,可以考虑的组合次数,这个配置写在文件中,不允许会话参数修改
。因为presto的优化值得是尝试出执行计划的最优解,当有n张表连接的时候,presto将尝试n次幂的组合对,所有如果你不限制最大的对数那就废了
bash
optimizer.max-reordered-joins=5
**49、**0.215版本开始,presto添加了对执行计划的动态调整,优先大数据分组的处理,并缓解资源争抢导致的节点高压,在0.239版本开始这个能力默认开启,并且0.243版本中删除了启停的配置项
这里要说一个容易混淆的点,这里提到的分组(grouped_execution),指的是presto的MPP架构下Exchange执行时,对所有数据操作分布到多个节点并行处理的一种优化手段,比如sum时多个节点一起执行最后聚合结果,而不是group by这种sql中的分组,分布式join处理也可以互补
bash
SET SESSION dynamic_schedule_for_grouped_execution=true
或者config文件中全局设置
dynamic-schedule-for-grouped-execution=true
**50、**0.239版本开始,默认对发生聚合和连接操作的任务,使用分组聚合优化
bash
SET SESSION grouped_execution_for_aggregation=true
SET SESSION grouped_execution_for_join=true
或者config文件中全局设置
grouped-execution-for-aggregation-enabled=true
grouped-execution-for-join-enabled=true
但是到了0.243版本,presto把上面的配置统一到了一个中,上面的配置被废弃了
bash
grouped-execution-enabled=true
SET SESSION grouped_execution=true
**51、**0.222版本开始,对没有聚合、连接等操作的任务也支持grouped分组聚合执行,比如普通的select这种,但是这是个实现性的功能,在0.239版本删掉了
bash
SET SESSION grouped_execution_for_eligible_table_scans=true
experimental.grouped-execution-for-eligible-table-scans-enabled=true
0.224版本开始,和上面发生聚合与连接的任务一样,也可以控制生成的虚拟桶数来提高执行效率,不过只有会话参数
bash
SET SESSION hive.virtual_bucket_count=50
**52、**到了0.234版本中加入了通过数据上游缓冲区的利用率,来自动调整写入执行器写入性能的能力
bash
SET SESSION optimized_scale_writer_producer_buffer=true
也可以写在config文件中
optimized-scale-writer-producer-buffer=true
**53、**0.234版开始,可以指定集群中在运行的任务数到达多少之后就不再调度新的任务了,从而提升集群的稳定性,但是很少用,通常都是通过资源组来完成这个限制,如果和资源组共用,会交叉影响
bash
experimental.max-total-running-task-count-to-not-execute-new-query=100
**54、**到了0.238版本,对于连接查询中的空条件,presto做出了优化处理,来降低空连接的资源消耗,在config配置中开启。不过在0.250左右不再允许配置了,presto默认会优化
bash
optimize-nulls-in-joins=true
**55、**0.239版本开始,对于重复的查询条件presto只会执行一次,如果有影响可以使用会话参数关闭
bash
SET SESSION optimize_common_sub_expressions=false
**56、**0.240版本开始,对于嵌套数据,比如hive的复杂类型,可以尝试直接读取精确的键值,而不是读取整个字段的数据
bash
SET SESSION pushdown_dereference_enabled=true
或者在config文件中写死
experimental.pushdown-dereference-enabled=true
**57、**0.248版本开始,可以关闭presto处理hive数据时,为空数据对象创建空文件的行为,来提高处理效率,比如空桶等,在hive的catalog文件中配置
bash
hive.create-empty-bucket-files-for-temporary-table=false
**58、**0.251版本开始,presto提供了一种保障策略,当任务节点出现异常,会把异常消息记录并对其他任务做出一定的调控
bash
# 启停开关
internal-communication.memoize-dead-nodes-enabled=true
**59、**0.252版本开始,presto提供了对任务的自动重试配置,在config文件中设置非0值即启用
bash
per-query-retry-limit=2
**60、**如果你的hive元数据服务配置了多个实例,对于presot来讲默认是高可用的访问方式,大白话就是顺序访问,直到成功连接。但是在0.253版本开始,可以选择让presto以负载均衡的方式访问这些元数据服务实例,只需在hive的catalog中添加一个配置
bash
hive.metastore.load-balancing-enabled=true
**61、**presto在0.257版本开始支持了offset子句,需要通过配置打开能力支持
bash
SET SESSION offset_clause_enabled=true
或者写在config文件中
offset-clause-enabled=true
**62、**presto在0.270开始,如果去重操作的基数在一个固定的上限以内,presto提供了底层执行对哈希优化的算法
bash
SET SESSION hash_based_distinct_limit_enabled=true
或者写在config文件中
hash-based-distinct-limit-enabled=true
而这个上限,通过配置调整,默认是10000
bash
SET SESSION hash_based_distinct_limit_threshold=10000
hash-based-distinct-limit-threshold=10000
注意这个能力在0.279被删掉了,被融合在了SET SESSION quick_distinct_limit_enabled=true
中,用来优化DISTINCT 和 LIMIT
共存的语句
**63、**presto在0.272开始,presto加入了流聚合提高处理性能,说大白话就是减少中间结果的生成开销,不一次加载所有数据,而是如flink流计算那样,从0到1的逐渐加载数据并计算
但是有个限制!!流聚合只能生效在分组字段和排序字段相同的场景下
bash
SET SESSION streaming_for_partial_aggregation_enabled=true
写在config中
streaming-for-partial-aggregation-enabled=true
不过有个要注意的情况!!按照官网的说法,如果对hive数据开启流聚合,presto提供了单独的流聚合支持,可以在分组键是排序键子集的情况下也能用流聚合,但是在具体使用的时候发现这个参数不支持,即使退出了版本到0.272
bash
SET SESSION streaming_aggregation_enabled=true
写在hive的catalog中
hive.streaming-aggregation-enabled=true
不过在0.273版本中hive流聚合的配置被改成了新的
bash
SET SESSION order_based_execution_enabled=true
hive.order-based-execution-enabled=true
**64、**presto在0.272开始加入了自适应调度模式
bash
SET SESSION execution_policy
可选值:
all-at-once 默认值,一次调度所有stage阶段,保持并行执行任务
phased 需要配合 `max_stage_count_for_eager_scheduling`会话设置一个阈值,在stage数量到达这个阈值之上时,从上游到下游顺序调度stage,如果在阈值之下则采用默认的模式
SET SESSION max_stage_count_for_eager_scheduling
**65、**presto在0.274版本开始,对查询有约束的表数据提供了优化性能,比如mysql的主键、非空、唯一等等这种表约束
bash
SET SESSION exploit_constraints=true
或者写在config文件中
optimizer.exploit-constraints=true
**66、**presto在0.274版本开始,如果你的sql逻辑中排序字段是分组字段的子集,则可以开启presto的执行优化,可以减少内存使用提高聚合性能
bash
SET SESSION segmented_aggregation_enabled=true
或者写在config中
optimizer.segmented-aggregation-enabled=true
**67、**presto在0.274版本开始,处理hive数据时,如果排序字段是分组字段的子集,presto提供了分段聚合的能力,个人理解类似于hive的conbiner
bash
SET SESSION order_based_execution_enabled=true
或者写在hive的catalog中
hive.order-based-execution-enabled=true
**68、**presto在0.281版本开始,如果你的sql中聚合操作有多个类似的过滤子句,就比如使用count(1) filter(where 条件)
求多个情况下的count数,这种语句presto提供了合并执行计划的能力,可以通过会话参数打开
bash
SET SESSION merge_aggs_with_and_without_filter=true
**69、**从0.291版本开始,如果你的任务对于集群来讲相当小,比如任务节点都是单台上TB内存的机器,这个时候你任务处理的数据量不到100G,这种情况,你可以通过配置让这个任务只在单节点上执行
bash
SET SESSION single_node_execution_enabled=true
或者写在config文件里
single-node-execution-enabled=true
**70、**如果你的sql在写入语句中使用了UNION ALL
,注意UNION
不在考虑范围内,此时你可以让presto并行写入不同的select集合,着可以提高写入效率,并降低集群内存资源负载。这个参数的版本信息并没有找到,不过0.260以后是明确可以正常使用的,之前的版本需要自己试一下
bash
SET SESSION push_table_write_through_union=true
或者写在config文件中
optimizer.push-table-write-through-union=true
**71、**在0.289版本开始,presto提供了一种将低估值任务因素直接视为未知的策略,防止presto做出过度优化的执行计划,甚至过度到影响任务效率
bash
SET SESSION treat-low-confidence-zero-estimation-as-unknown=true
或者写在config文件中
optimizer.treat-low-confidence-zero-estimation-as-unknown=true
**72、**在0.289版本开始,presto可以根据HBO的结果来重试查询任务,并自适应执行计划。HBO说白了就是presto对往期执行计划的消息收集与判断,具体信息可以看官网的资料-》https://prestodb.io/docs/current/optimizer/history-based-optimization.html#configuration-properties
bash
SET SESSION retry-query-with-history-based-optimization=true
或者写在config中
optimizer.retry-query-with-history-based-optimization=true
**73、**在0.290+的版本,一批次提交多个查询时,可以让presto缓冲处理表和列的元数据信息
bash
SET SESSION useJdbcMetadataCache=true