Presto集群内存不足时保护机制

为了防止集群里节点OOM,Presto有个循环线程来获取当前集群节点和集群整体内存占用情况。通过这篇文章:Presto内存管理相关参数设置 我们知道Presto里分为RESERVED_POOL和GENERAL_POOL。

判断节点是否阻塞(内存不足)

如果使用RESERVED_POOL(意思是说最大SQL使用这个POOL),那判断集群内存超出内存的方法就是:

1、RESERVED_POOL内存被SQL占用了

2、GENERAL_POOL里有被阻塞的Node

因为RESERVED_POOL会导致内存浪费,我们集群配置参数没有使用这个POOL,只使用了GENERAL_POOL,所以只需要查看下GENERAL_POOL是怎么判断节点是否Block住的。

1
2
3
4
if (poolInfo.getFreeBytes() + poolInfo.getReservedRevocableBytes() <= 0) {
blockedNodes++;
}

getReservedRevocableBytes 这个是用于获取spill到磁盘的内存,目前我们集群是不允许内存Spill到磁盘的,因为Presto面向的是ad-hoc场景,要求是快,如果说需要spill到磁盘,那spark是一个更好的选择,且早期版本Presto spill到磁盘之前测试过稳定性比较差,场景也比较少。

所以就判断GENERAL_POOL里是否还有剩余内存,如果小于等于0,那就表示该节点是个Block状态。

Read More

Presto内存管理相关参数设置

背景

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

两种内存

Presto里面内存只有2种内存,一种是user memory,另一种是system memory。system 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

1
2
deprecated.legacy-system-pool-enabled

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

Read More

Presto ORC及其性能优化

简介

ORC的全称是(Optimized Row Columnar),其是为了加速Hive查询以及节省Hadoop磁盘空间而生的,其使用列式存储,支持多种文件压缩方式。由于其被广泛应用在Hadoop系统中,Presto 0.77版本在Hive Connector里实现了ORC Reader。

ORC文件结构

上图(图1)来自网络,有很多文章通过这张图片介绍了ORC文件结构,我这里就不多啰嗦了,我们直接通过数据来看文件格式吧。

Read More

Presto System load过高问题调研

背景

我们Presto有个集群,每6.5天会出现System load过高问题,这个集群有个特点,只服务于一个业务方,且SQL基本相似。如图所示:Sys load很高(20-40%),严重影响查询性能。

业务SQL查询时间表现为:

ScanFilterAndProjectOperator(Source Stage)阶段有机器有明显的长尾现象,比如20台机器,正常这个Operator执行时间只需要1S,但是有几台机器会耗时几分钟。而重启服务后,查询恢复正常。

Read More

Presto兼容Hive SQL的一些改造工作

前言

Presto是一款优秀的分布式SQL查询引擎,适用于即席查询和报表分析等业务,其使用了ANSI SQL语法和语义,使用标准是SQL-92和SQL:2016。但是因为很多业务方一直使用Hive离线引擎来做SQL分析,而Hive使用类似SQL的语法(HQL)。为了使用户能平滑的将业务迁移到Presto上或者能让SQL同时跑到Presto及Hive引擎上,我们对Presto语法及一些算子等做了二次兼容开发,来最大限度降低用户迁移成本。接下来我们介绍下我们的主要兼容工作。

一、权限认证

Presto默认如果使用Password,那么必须使用Kerberos协议。因为公司离线数据没有Kerberos协议,所以我们改进了权限认证机制,与离线复用一套权限机制,用户只需要去离线申请权限,指定用户名和密码,即可查询Presto引擎和访问离线数据,并且提供了以下几种方式访问公司Presto,且与公司离线权限体系打通,分别为JDBC、Cli、Go、Python、R、NodeJS。

二、行为修改

整数相除返回浮点数

Presto整数相除沿用了Java整数相除的特性,我们需要修改函数算子行为,如IntegerOperators,将divide相关的函数修改为返回浮点数结果。比如:

Read More

Presto的一些基本概念

模型

Presto 是 Facebook 开源的 MPP (Massive Parallel Processing) SQL 引擎,其理念来源于一个叫 Volcano 的并行数据库,该数据库提出了一个并行执行 SQL 的模型,核心思想就是 Operator Model 和 Iterator Model。

  • Operator Model
    即通过各种 Operator 组成一棵树,树的根节点负责结果输出,树的叶子节点是各种 TableScan。这棵树被称作 Plan(执行计划),数据库里又被细分为逻辑执行计划和物理执行计划。这棵树是由 SQL 经过词法、语法分析及语义分析后,生成一个 AST(Abstract Syntax Tree),一般经过 Visitor 模式遍历后生成。原始数据通过叶子节点 TableScan 读取数据,然后经过各个 Operator的计算,包括(TableScan、Project、Filter、Exchange、Agg、Join、TaskOutput等)产出结果。
  • Iterator Model
    顾名思义就是一个递归迭代过程,Plan 树的各节点有三个状态,Open、GetNext及Close。从根节点 Open 开始递归调用 GetNext 获取数据,即父节点递归调用子节点接口直到没有结果为止,然后Close。

Read More

Presto内存管理原理和调优

内存池

Presto有三种内存池,分别为GENERAL_POOL、RESERVED_POOL、SYSTEM_POOL。这三个内存池占用的内存大小是由下面算法进行分配的:

1
2
3
4
5
6
7
8
9
builder.put(RESERVED_POOL, new MemoryPool(RESERVED_POOL, config.getMaxQueryMemoryPerNode()));

builder.put(SYSTEM_POOL, new MemoryPool(SYSTEM_POOL, systemMemoryConfig.getReservedSystemMemory()));

long maxHeap = Runtime.getRuntime().maxMemory();
maxMemory = new DataSize(maxHeap - systemMemoryConfig.getReservedSystemMemory().toBytes(), BYTE);
DataSize generalPoolSize = new DataSize(Math.max(0, maxMemory.toBytes() - config.getMaxQueryMemoryPerNode().toBytes()), BYTE);
builder.put(GENERAL_POOL, new MemoryPool(GENERAL_POOL, generalPoolSize));

梳理这块代码对应的逻辑和配置文件,得出RESERVED_POOL大小由config.properties里的query.max-memory-per-node指定;SYSTEM_POOL由config.properties里的resources.reserved-system-memory指定,如果不指定,默认值为Runtime.getRuntime().maxMemory() * 0.4,即0.4 * Xmx值;而GENERAL_POOL值为 总内存(Xmx值)- 预留的(max-memory-per-node)- 系统的(0.4 * Xmx)。

而这三种内存池分别用于不同的地方,分析代码和阅读Presto开发手册,大体可以定位出:

  • GENERAL_POOL is the memory pool used by the physical operators in a query.
  • SYSTEM_POOL is mostly used by the exchange buffers and readers/writers.
  • RESERVED_POOL is for running a large query when the general pool becomes full.

Read More