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

112 阅读5分钟

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

1. 概述

1.1. 大数据与 OLAP 的演进

OLAP(OnLine Analytical Processing)对业务数据执行多维分析,并提供复杂计算,趋势分析和复杂数据建模的能力。是许多商务智能(BI)应用程序背后的技术。

OLAP 核心概念:维度、度量

常见的 OLAP 引擎:

  • 与计算引擎:Kylin、Druid
  • 批式处理引擎:Hive、Saprk
  • 流式处理引擎:Flink
  • 交互式处理引擎:Presto、Clickhosue、Doris

1.2. Presto 设计思想

Presto 最初由 Facebook 研发的构建于 Hadoop/HDFS 系统之上的 PB 集交互式分析引擎,具有以下特点:

  • 多租户任务的管理与调度
  • 多数据源联邦查询
  • 支持内存优化计算
  • Pipline 式数据处理

2. Presto 基础原理和概念

2.1. 基础原理与概念

服务相关

image-20220803102720230.png

  • Coordinator

    • 解析 SQL 语句
    • 生成执行计划
    • 分发执行任务给 Worker 节点
  • Worker

    • 执行 Task 处理数据
    • 与其他 Worker 交互传输数据

数据源相关

image-20220803103002056.png

  • Connector:一个 Connector 代表一种数据源,可以认为 Connector 是由 Presto 提供的适配多数据源的统一接口。
  • Catalog:管理员辕信息与实际数据的映射关系。

Query 相关

  • Query:基于 SQL parser 后获得的执行计划。
  • Stage:根据是否需要 shuffle 将 Query 拆分成不同的 subplan,欸一个 subplan 是一个 stage。
  • Fragment:基本等价于 stage,属于不同阶段的称呼。
  • Task:单个 Worker 节点上的最小资源管理单元,在一个节点上,一个 Stage 只有一个 Task,一个 Query 可能有多个 Task。
  • Pipeline:Stage 按照 LocalExchange 切分为若干 Operator 集合,每个 Operator 集合定义一个 Pipeline。
  • Driver:Pipeline 的可执行实体,Pipeline 和 Driver 的关系可类比为程序和进程,是最小的执行单元,通过火山迭代模型执行每一个 Operator。
  • Split:输入数据描述(数据实体是 Page),数量上和 Driver 一一对应,不仅代表实际数据源 split,也代表了不同 stage 间传输的数据。
  • Operator:最小物理算子。

数据传输相关

  • Exchange:表示不同 Stage 间的数据传输,大多数意义下等价于 Shuffle。
  • LocalExchange:Stage 内的 rehash 操作,常用于提高并行处理数据的能力(Task 在 Presto 中只是最小的容器,而不是最小的执行单元),默认值是16。

2.2. 核心组件结构介绍

Presto 结构图

image-20220803104359902.png

服务发现

Discovery Service:

  1. Worker 配置文件配置 Discovery Service 地址
  2. Worker 节点启动后会向 Discovery Service 注册
  3. Coordinator 从 Discovery Service 获取 Worker 的地址

通信机制

  • 通信机制

    1. Presto Client / JDBC Client 与 Server 间通信 ---- htpp

    2. Coordinator 与 Worker 间的通信 ---- Thrift/Http

    3. Worker 与 Worker 间的通信 ---- Thrift/Http

    Thrift 具有更好的数据编码能力,Http 1.1 还不支持头部信息的压缩,Thrift 具有更好的数据压缩能力

  • 节点状态

    • ACTIVE
    • INACTIVE
    • SHUTDOWN

3. Presto 重要机制

3.1. 多租户资源管理

Resource Group

  • 类似 Yarn 多级队列的资源管理方式
  • 基于 CPU、MEMORY、SQL 执行数进行资源使用量限制
  • 优点:轻量的 Query 级别的多级队列资源管理模式
  • 缺点:存在一定的滞后性,只会对 Group 中正在运行的 SQL 进行判断

物理计划生成

  1. Antlr4 解析生成 AST
  2. 转换成 Logical Plan
  3. 按照是都存在 Shuffle(Exchange),切分成不同的 Stage(Fragment)

3.2. 多租户下的任务调度

Stage 调度

  • Stage 的调度策略

    • AllAtOnceExecutionPolicy(同时调度)

      延迟点,会存在任务空跑

    • PhasedExecutionPolicy(分阶段调度)不代表每个 stage 都分开调度,典型应用场景(join 查询)

      • Build 端:游标构建用 join 的 hashtable
      • Probe 端:对用户左表数据进行探查,需要等待 build 端完成
      • build 端构建 hashtable 端时,probe 端一直在空跑的

      有一定延迟,节省部分资源

Task 调度

  • 如何确定 Task 的数量

    • Source:根据数据 meta 决定分配多少个节点
    • Fixed:hash partition count 确定,如集群节点数量
    • Sink:汇聚结果,一台机器
    • Scaled:无分区限制,可扩展,如 write 数据
    • Coordinator_only:只需要 coodinator 参与
  • 选择什么样的节点

    • HARD_AFFINITY:计算、存储 Local 模式,保障计算与存储在同一节点,减少数据传输
    • SOFT_AFFINITY:基于某些特定算法,如一只 HASH 函数,常用于缓存场景,保证相似的 Task 调度到同一个 Worker
    • NO_PREFERENCE:随机选取,常用于普通的纯计算 Task

Split 调度

  • FIFO:顺序执行,绝对公平
  • 优先级调度:快速响应

3.3. 内存计算

Pipeline 化的数据处理

Pipeline(按 LocalExchange 拆分):

  • Pipeline 的引入更好的实现算子间的并行
  • 语义上保证了每个 Task 内的数据流式处理

Back Presure Mechanism

  • 控制 split 生成流程
  • 控制 operator 的执行
  1. targetConcurrency auto-scale-out:定时检查,如果 OutputBuffers 使用率低于 0.5 (下游消费较快,需要提高生产速度),并发度 +1
  2. sink.max-buffer-size 写入 buffer 的大小控制
  3. exhange.max0buffer-size 读取 buffer 的大小控制

达到最大值时 operator 会进入阻塞状态。

3.4. 多数据源联邦查询

将各个数据源进行统一的抽象,最后由 presto server 进行统一的物理执行

image-20220803112330433.png

局限性

  1. 元数据管理与映射(每个 connector 管理一套数据服务)
  2. 谓词下推
  3. 数据源分片

4. 性能优化实践

常用性能分析工具

  • Grfana:埋点、系统指标如 CPU、内存、网络等的可视化界面,时序化的数据显示

  • Java 相关指令

    • Jstack 查看 Java 线程栈信息,排查是否有死锁,或者一场线程存在
    • JMX(Java Management Extensions)是一个为应用程序植入管理功能的框架, 常用来做一些监控指标的统计收集
    • JMAP & GC 日志等等内存分析工具
  • 线上问题排查工具

    • Arthas

      • Watch
      • Trace
    • Flame Figure/火焰图:用于分析热点代码占用大量 CPU,从而导致服务性能下降的情况

  • Presto UI

    • Query 级别统计信息
    • Logical Plan
    • Stage、Task 信息
    • Worker 状态信息