记一次Presto Worker OOM的查找过程

背景

最近Presto集群又上线了几个新业务,伴之而来的是OOM很频繁,且发生时间多在早晨8点左右,线上稳定性是高优需要解决的,所以查找了下导致Presto集群OOM的原因,发现了一些问题,这里抛砖引玉下,可能其他使用Presto的用户也会遇到类似的问题。

排查过程

我给一些业务划分了不同的label,这里说明下我们把Presto引擎改进了下,可以动态将机器划分不同的label,这样SQL查询时候指定不同的label,SQL调度时只根据指定的label查找机器即可。之后发现一个业务方的SQL会导致集群OOM。具体表现为,多次Full GC,之后OOM,看GC日志第一感觉应该是有内存泄露。

我通过审计日志(之前通过event-listener实现了个日志审计模块)拿到OOM时2K左右条SQL,发现SQL都是简单的SQL,类似这种:

1
SELECT * FROM table WHERE year='2020' AND month='06' AND day='01' LIMIT 10;

根据SQL,我猜测可能以下2种原因导致了OOM:

  • 查询的表存在Hive视图(我让Presto支持了Hive视图)
  • 异常SQL触发了内存泄露

Read More

PrestoDB和PrestoSQL比较及选择

Presto 社区分家后搞了2个项目,分别为 PrestoDB 和 PrestoSQL,同时他们都成立了自己的基金会。而去年国庆时候,abei写了篇文章比对了2个分支的进展,链接见:PrestoDB VS PrestoSQL发展比较。 而现在已经分家17个月了,那我们简单梳理下这2个分支的主要核心功能:

PrestoDB:

  • Connector:ElasticSearch 及 Druid
  • Master 和Worker 通信协议支持二进制
  • Orc 及 Parquet读写性能优化
  • Hive写数据支持指定压缩格式
  • task通信协议可以指定 thrift
  • spi pushdown
  • MapReduce-style shuffle,支持部分 etl 任务及大查询
  • fix bug 及 improve performace

PrestoSQL:

  • Connector:ElasticSearch和MemSQL
  • spi pushdown
  • S3优化读取
  • join 延时物化
  • 大量的 fix bug 及 improve performance

Read More

Presto调度task选择Worker方法

Presto调度task方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
public final class SystemPartitioningHandle
implements ConnectorPartitioningHandle
{
private enum SystemPartitioning
{
SINGLE,
FIXED,
SOURCE,
SCALED,
COORDINATOR_ONLY,
ARBITRARY
}
}

常见的场景主要包含SINGLE、FIXED及SOURCE类型,其中SINGLE表示最后数据的汇总输出,FIXED表示中间数据的计算,如JOIN等,SOURCE类型表示与源数据打交道的类型。

以下SQL为例:

1
select * from (select * from 1test join 2test1 on 1test.id = 2test1.123id);

Read More

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
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
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