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

分布式SQL查询引擎Presto原理介绍

前言

我们实时引擎组新引入了一款分布式SQL查询引擎,名字叫Presto,目前已经调研和测试了2个月了,并且期间某平台也从impala平台迁入到了Presto平台,查询性能有了2-3倍的提升(各种原因导致),所以本文将结合作者这段时间的测试和调研研究,来揭开Presto的神秘面纱。

Presto是神马

Presto是由Facebook开发的一个分布式SQL查询引擎, 它被设计为用来专门进行高速、实时的数据分析。它的产生是为了解决Hive的MapReduce模型太慢以及不能通过BI或Dashboards直接展现HDFS数据等问题。Presto是一个纯粹的计算引擎,它不存储数据,其通过Connector获取第三方Storage服务的数据。

历史

  • 2012年秋季,Facebook启动Presto项目
  • 2013年冬季,Presto开源
  • 2017年11月,11888 commits,203 releases,198 contributors

功能和优点

  • Ad-hoc,期望查询时间秒级或几分钟
  • 比Hive快10倍
  • 支持多数据源,如Hive、Kafka、MySQL、MonogoDB、Redis、JMX等,也可自己实现Connector
  • Client Protocol: HTTP+JSON, support various languages(Python, Ruby, PHP, Node.js Java)
  • 支持JDBC/ODBC连接
  • ANSI SQL,支持窗口函数,join,聚合,复杂查询等

架构

  • Master-Slave架构
  • 三个模块
  • Coordinator、Discovery Service、Worker
  • Connector

Read More

说说常见搜索引擎的分布式解决方法

随着索引数据的增大以及请求的增多,分布式搜索是最好的一种解决方案,主要解决两个问题,其一是能让单台机器load所有索引数据到内存中,其二是请求延时大,解决请求latency问题。我之前为团队写了篇专利,内容是关于分布式搜索解决方案的,所以粗略的看了下大部分开源的搜索引擎是怎么实现分布式的,后面的文章我会简单说下常见的搜索引擎的分布式解决方案。

首先我们先说下几个简单概念,分布式搜索都是M*N(横向切分数据,纵向切分流量)这个维度去解决问题的,虽然不同产品或场景概念不完全相同,读者可以简单认为一份完整的数据,被均分为M份,每一份被称为一个分配(Shard或者Partition),然后提供对每个Shard提供N份副本(Replica)。那么分布式的设计就围绕着以下问题:

  • 如何选择合适的分片(Shard),副本(Replica)的数量
  • 如何做路由,即怎么在所有Shard里找到一份完整的数据(找到对应的机器列表)
  • 如何做负载均衡
  • 如果提高服务的可扩展性
  • 如何提高服务的服务能力(QPS),当索引和搜索并发量增大时,如何平滑解决
  • 如何更新索引,全量和增量索引的更新解决方法
  • 如果提高服务的稳定性,单台服务挂掉怎么不影响整体服务等等

下面就说下常见的搜索引擎的分布式解决方案,因为开源的搜索产品基本上都没有在工作中用过,对代码细节并不是太了解,只是研究了下其原理,所以理解的会有些偏差,看官们如果发现错误直接指出即可。

Read More