Presto 架构原理与优化介绍| 青训营笔记

537 阅读5分钟

这是我参与「第四届青训营 」笔记创作活动的第11天。

Presto 简介

Presto是Facebook开源的查询分析引擎,在国内京东用的比较成熟。Presto数据处理能力到达PB级别,支持查询数据源有Hive、Kafka、Cassandra、Redis、Mongodb、SQL server等,在工作应用当中,Presto的查询性能比Hive要高40%以上。

image.png

其具有如下的特点:

  • 多租户任务的管理与调度:它支持并发执行数百个内存、I/O 以及 CPU 密集型的负载查询,并支持集群规模扩展到上千个节点;
  • 多数据源联邦查询:它可以由开发者利用开放接口自定义开发针对不同数据源的连接器(Connector),从而支持跨多种不同数据源的联邦数据查询;
  • 支持内存化计算:把计算嵌入到内存里面去,内存变成存储+计算的利器,在存储/读取数据的同时完成运算,减少了计算过程中的数据存取的耗费。把计算都转化为带权重加和计算,把权重存在内存单元中,让内存单元具备计算能力。
  • pipeline式数据处理:将许多算法模型串联起来,然后依次对数据进行处理,得到最终的分类结果。

应用场景

Presto 的应用场景非常广泛,接下来我们主要介绍几种使用比较广泛的场景进行介绍。

  1. 交互式分析:交互式查询是 Presto 主打的应用场景,Presto 的即席计算特性和内部设计机制就是为了能够更好地支持用户进行交互式分析。可以类比用户基于 Hive 交互式查询 HDFS 中的数据,用户可以基于 Presto 查询各种不同的数据源的数据。
  2. 批量 ETL。
  3. Facebook 的 A/B Test 基础架构也是基于 Presto 构建的。

Presto 之所以能在各个内存计算型数据库中脱颖而出,在于以下几点:

  • 清晰的架构,是一个能够独立运行的系统,不依赖于任何其他外部系统。例如调度,presto 自身提供了对集群的监控,可以根据监控信息完成调度。
  • 简单的数据结构,列式存储,逻辑行,大部分数据都可以轻易的转化成 presto 所需要的这种数据结构。
  • 丰富的插件接口,完美对接外部存储系统,或者添加自定义的函数。

Presto 执行流程

8ff06c99fa5e7eba083740edfaeb42f.png

  1. Client 使用 HTTP 协议发送一个 query 请求。
  2. 通过 Discovery Server 发现可用的 Server。
  3. Coordinator 构建查询计划(通过 Anltr3 解析为 AST(抽象语法树),然后通过 Connector 获取原始数据的 Metadata 信息,生成分发计划和执行计划)。
  4. Coordinator 向 Worker 发送任务。
  5. Worker 通过 Connector 插件读取数据。
  6. Worker 在内存里执行任务(Worker 是纯内存型计算引擎)。
  7. Worker 将数据返回给 Coordinator,汇总之后再响应客户端。

Presto 架构详解

image.png

Presto 查询引擎是一个 Master-Slave 的架构,由一个 Coordinator 节点,一个 Discovery Server 节点,多个 Worker 节点组成,Discovery Server 通常内嵌于 Coordinator 节点中。

Coordinator

Coordinator 的作用是:

  • 从用户获得 SQL 语句
  • 解析 SQL 语句
  • 规划查询的执行计划
  • 管理 worker 节点状态
  • Coordinator 是 Presto 集群的大脑,并且是负责和客户端沟通。用户通过 PrestoCLI、JDBC、ODBC 驱动、其他语言工具库等工具和 coordinator 进行交互。Coordinator 从客户端接受 SQL 语句,例如 select 语句,才能进行计算。

  • 每个 Presto 集群必须有一个 coordinator,可以有一个或多个 worker。在开发和测试环境中,一个 Presto 进程可以同时配置成两种角色。

  • Coordinator 追踪每个 worker 上的活动,并且协调查询的执行过程。

  • Coordinator 给查询创建了一个包含多阶段的逻辑模型,一旦接受了 SQL 语句,Coordinator 就负责解析、分析、规划、调度查询在多个 worker 节点上的执行过程,语句被翻译成一系列的任务,跑在多个 worker 节点上。

  • worker 一边处理数据,结果会被 coordinator 拿走并且放到 output 缓存区上,暴露给客户端。

  • 一旦输出缓冲区被客户完全读取,coordinator 会代表客户端向 worker 读取更多数据。

  • worker 节点,和数据源打交道,从数据源获取数据。因此,客户端源源不断的读取数据,数据源源源不断的提供数据,直到查询执行结束。

  • Coordinator 通过基于 HTTP和Thrift 的协议和 worker、客户端之间进行通信。

Workers

Presto Worker的不同状态

  1. Active
  2. InActive
  3. Shutdown
  • Presto 的 worker 是 Presto 集群中的一个服务。它负责运行 coordinator 指派给它的任务,并处理数据。worker 节点通过连接器(connector)向数据源获取数据,并且相互之间可以交换数据。最终结果会传递给 coordinator。coordinator 负责从 worker 获取最终结果,并传递给客户端。

  • Worker 之间的通信、worker 和 coordinator 之间的通信采用基于 HTTP 的协议。下图展示了多个 worker 如何从数据源获取数据,并且合作处理数据的流程。直到某一个 worker 把数据提供给了 coordinator。

Discovery server

  • Presto 使用 Discovery server来查找集群中所有节点
  • 每个 Presto 实例在启动时都会向 Discovery server注册自己。Presto 为了简化部署,并且为了避免再增加一个新的Discovery server,Presto 的 Coordinator 可以运行一个内嵌在 Coordinator 里面的 Discovery server。内嵌的 Discovery 服务与 Presto 共享 HTTP Server 并且使用相同的端口。

上图给我们展示了客户端、coordinator,worker 之间的通信。

presto引擎对比

与hive、SparkSQL对比结果图