前言
Facebook 的数据仓库构建在 HDFS 集群之上。在很早之前,为了能够方便分析存储在 Hadoop 上的数据,Facebook 开发了 Hive 系统,使得科学家和分析师可以使用 SQL 来方便的进行数据分析,但是 Hive 使用的是 MapReduce 作为底层的计算框架,随着数据分析的场景和数据量越来越大,Hive 的分析速度越来越慢,可能得花费数小时才能完成。而且 Facebook 也尝试使用外部的一些项目,但是都无法满足自己的需求,基于这些情况,Facebook 从 2012 年秋季开始开发一个新的计算引擎,这也就是我们熟悉的 Presto。
Presto 的核心目标就是提供交互式查询,也就是我们常说的 Ad-Hoc Query,很多公司都使用它作为 OLAP 计算引擎。但是随着近年来业务场景越来越复杂,除了交互式查询场景,很多公司也需要批处理;但是 Presto 作为一个 MPP 计算引擎,将一个 MPP 体系结构的数据库来处理海量数据集的批处理是一个非常困难的问题,所以一种比较常见的做法是前端写一个适配器,对 SQL 进行预先处理,如果是一个即时查询就走 Presto,否则走 Spark。这么处理可以在一定程度解决我们的文档,但是两个计算引擎以及加上前面的一些 SQL 预处理大大加大我们系统的复杂度。
Presto Unlimited
在 Facebook,超过80%的新增批处理工作负载是在 Presto 上运行的。然而,内存密集型(memory-intensive )和长时间运行(long-running queries)的查询是 Presto 用户的主要痛点。我们很难判断查询将使用多少内存以及何时会达到内存限制,长时间运行的查询失败会导致重试,这会造成更严重的问题。为了解决 Presto 同时能够处理即时查询和复杂 ETL ,Facebook 开发了代号为 Presto Unlimited 的项目。Presto Unlimited 的设计目标是为了解决可伸缩性的挑战,使得一套 Presto 系统既可以处理即时查询,也可以处理复杂的 ETL 查询。
Grouped Execution
为了解决内存密集型查询,Facebook 引入了 Grouped Execution, Grouped Execution 利用 table partitioning 来进一步提升查询性能。假设我们有以下查询,customer 和 orders 两张表都已经在 custkey 字段进行分桶(bucketedÿ