【presto】转载:Presto内存管理相关参数设置

转自:http://armsword.com/2019/11/13/the-configuration-settings-of-presto-memory-management/#more

背景

之前介绍过Presto内存管理和分配策略,但是那个是0.192版本,详细见:Presto内存管理原理和调优 ,0.201之后内存管理作了新的修改,所以重新简单分析下,然后给出一个配置模板,希望对使用Presto的同学有帮助。

两种内存

Presto里面内存只有2种内存,一种是user memory,另一种是system memorysystem memory用于input/output/exchange buffers等,user memory 用于hash join、agg这些。

内存池

0.201之前有3种内存POOL,分别是

  • GENERAL_POOL
  • RESERVED_POOL
  • SYSTEM_POOL。

但是0.201之后,默认SYSTEM_POOL是不开启的,以下参数控制,默认值为false

deprecated.legacy-system-pool-enabled

那SYSTEM_POOL不使用了,这块内存怎么控制呢,去代码里确认了下:

SqlTaskManager#createQueryContext

private QueryContext createQueryContext(
            QueryId queryId,
            LocalMemoryManager localMemoryManager,
            NodeMemoryConfig nodeMemoryConfig,
            LocalSpillManager localSpillManager,
            GcMonitor gcMonitor,
            DataSize maxQueryUserMemoryPerNode,
            DataSize maxQueryTotalMemoryPerNode,
            DataSize maxQuerySpillPerNode)
    {
        if (nodeMemoryConfig.isLegacySystemPoolEnabled()) {
            Optional<MemoryPool> systemPool = localMemoryManager.getSystemPool();
            verify(systemPool.isPresent(), "systemPool must be present");
            return new LegacyQueryContext(
                    queryId,
                    maxQueryUserMemoryPerNode,
                    localMemoryManager.getGeneralPool(),
                    systemPool.get(),
                    gcMonitor,
                    taskNotificationExecutor,
                    driverYieldExecutor,
                    maxQuerySpillPerNode,
                    localSpillManager.getSpillSpaceTracker());
        }
 
        return new DefaultQueryContext(
                queryId,
                maxQueryUserMemoryPerNode,
                maxQueryTotalMemoryPerNode,
                localMemoryManager.getGeneralPool(),
                gcMonitor,
                taskNotificationExecutor,
                driverYieldExecutor,
                maxQuerySpillPerNode,
                localSpillManager.getSpillSpaceTracker());
    }
}

可以看到systemPool.get()被替换为了localMemoryManager.getGeneralPool(),所以GENERAL_POOL扮演了之前GENERAL_POOL及SYSTEM_POOL的作用,提供user memorysystem memory

说完SYSTEM_POOL,再说下RESERVED_POOLRESERVED_POOL作用就是当GENERAL_POOL满的时候,将最占用内存的SQL分配到这块内存上来,但是实际使用时,这块内存很少会被使用,原因是,
一般使用Presto的业务是用来SQL提速的,不会使用spill disk功能,第二为了服务的稳定性,会限制最大内存和Kill内存策略,所以会出现查询没有被分配到RESERVED_POOL之前,
SQL将会被系统Kill掉。第三是大查询一般会用Spark/Hive替代,所以这块RESERVED_POOL就会浪费掉了,如下图所示:
在这里插入图片描述

目前有9个SQL正在查询,都在使用GENERAL_POOL,RESERVED_POOL将会浪费掉。所以对于绝大部分Presto使用者,禁止掉RESERVED_POOL是正确的选择。

新的参数:

memory.heap-headroom-per-node

这个内存主要是第三方库的内存分配,无法被统计跟踪,默认值是XMX*0.3。

所以,Presto内存分配只需要考虑GENERAL_POOLheap-headroom-per-node

分配方法

既然Presto是一个纯内存OLAP引擎,那肯定不能让查询占用的内存无限大,需要参数控制SQL占用的最大内存,Presto内存管理包括了单机和集群粒度的内存,分别是:

query.max-memory-per-node: 单个Query在单个Worker上允许的最大user memory
query.max-total-memory-per-node: 单个Query在单个Worker上允许的最大user memory + system memory
query.max-memory: 单个Query在整个集群上允许的最大user memory
query.max-total-memory: 单个Query在整个集群上允许占用的最大user + system memory

而集群query.max-memoryquery.initial-hash-partitions控制,现在默认值为100,但是这个值受限于Worker个数,即值为min(100,Worker Nums)。老版本的默认值为8, 所以我一般还是用8来计算的,那query.max-memroy 一般稍小于query.max-memory-per-node*8即可(考虑到数据倾斜)。

根据代码和上面分析知道:

RESERVED_POOL = query.max-total-memory-per-node

所以新的

GENERAL_POOL = TotalMemory - ReservedPool - memory.heap-headroom-per-node

禁止掉RESERVED_POOL时:

GENERAL_POOL= TotalMemory - memory.heap-headroom-per-node

配置

综上,Presto合适的内存分配配置为如下,假如-Xmx80G,Worker数大于8台:

query.max-memory=120GB  # 默认为20GB,query.max-memory-per-node * 8 * 0.8 ,倾斜按照0.8算即可
query.max-memory-per-node=20GB   # 默认值0.1 * XMX,一般线上按照0.25*XMX算,这个最好结合自己并发,如果并发大,大查询多,值最好小一点,稳定性考虑
query.max-total-memory-per-node=32GB  # 默认值0.3*XMX,一般设置为0.4*XMX
experimental.reserved-pool-enabled=false  # 不使用RESERVED_POOL
memory.heap-headroom-per-node=16GB  # 默认0.3*XMX,一般使用的是0.2*XMX
query.low-memory-killer.policy=total-reservation-on-blocked-nodes  # Kill策略,干掉Blocked的最大查询,GENERAL_POOL满了,防止OOM

比如上面分配后,GENERAL_POOL为80GB - 16GB = 64GB,如下图所示,RESERVED_POOL不再存在。query.max-total-memory默认值为2*query.max-memory,这个参数可以保持默认值即可。

在这里插入图片描述

转自:http://armsword.com/2019/11/13/the-configuration-settings-of-presto-memory-management/#more

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值