这是我参与「第四届青训营」笔记创作活动的的第1天,很荣幸和大家齐聚在这里开启大数据之旅。
本次课程主要分为四个大板块:
1. 大数据体系和SQL
2. 常见的查询优化器
3. 社区开源实践
4. 前沿趋势
1.大数据体系和SQL
大数据体系-One SQL rules big data all
在课程开篇,老师提到:One SQL rules big data all,通过SQL处理所有的大数据。以下是大数据体系图:
大数据体系 | |||||||
|---|---|---|---|---|---|---|---|
| 业务应用 | BI报表 | 数据挖掘 | 营销分析 | 精准推荐 | 管控运维 | ||
| 数据开发 | Airflow\DAG | 集群创建 | |||||
| 权限管控 | Apache Ranger\GDPR | 集群创建 | |||||
| (分析 | 批式分析 | 实时分析 | 交互分析 | 消息队列 | 集群创建 | ||
| 引擎) | Spark | --- | Presto | 集群创建 | |||
| Hive | Flink | ClickHOUSE | 服务管理 | ||||
| --- | MR | Doris | 服务管理 | ||||
| 资源调度 | YARN/K8S | Kafka | 用户管理 | ||||
| 存储系统 | HDFS/HBase/NAS/Objects Stores/数据湖 | Pulsar | 监控报警 | ||||
| 基础设施 | ECS/存储/VPC | --- | NSQ | 日志查询 |
(如上表有错误,以下表为标准,上表为自己写巩固记忆)
其中,多个大数据计算引擎都支持 SQL作为更高抽象层次的计算入口:
SQL的处理流程,通过四个组件进行处理:
graph TD
Start --SQL--> Parser--AST--> Analyser--Logical Plan-->Optimizer--Physical Plan-->Executor
- SQL的处理流程-Parser
String -> AST ( abstract syntax tree )
词法分析:拆分字符串,得到关键词、数值常量、字符串常量、运算符号等token
语法分析:将token 组成AST node,最终得到一个AST
实现:递归下降(ClickHouse),Flex和Bison (PostgreSQL), JavaCC(Flink),Antlr(Presto, Spark)
其中Flex用来做词法分析,Bison用来做语法分析
- SQL的处理流程-Analyzer和 Logical Plan
Analyzer:
√ 检查并绑定Database,Table, Column等元信息
√ SQL的合法性检查,比如min/max/avg 的输入是数值
√ AST -> Logical Plan
Logical Plan:
√逻辑地描述SQL对应的分步骤计算操作
√计算操作:算子(operator)
-SQL的处理流程-查询优化
· SQL是一种声明式语言,用户只描述做什么,没有告诉数据库怎么做
· 目标:找到一个正确且执行代价最小的物理执行计划
· 查询优化器是数据库的大脑,最复杂的模块,很多相关问题都是NP的
· 一般SQL 越复杂,Join 的表越多,数据量越大,查询优化的息乂就题人,因为不同执行方式的性能差别可能有成百上千倍
-SQL的处理流程-查询优化
Plan Fragment:执行计划子树
√目标:最小化网络数据传输
√
利用上数据的物理分布(数据亲和性)
√增加Shuffle算子
Executor
√单机并行:cache , pipeline,SIMD
√多机并行:一个 fragment 对应多个实例
小结:
· One SQL rules big data all
· SQL需要依次经过Parser ,Analyzer,Optimizer和 Executor的处理
· 查询优化器是数据库的大脑,在大数据场景下对查询性能至关重要
· 查询优化器需要感知数据分布,充分利用数据的亲和性
· 查询优化器按照最小化网络数据传输的目标把逻辑计划拆分成多个物理计划片段
2.常见的查询优化器
2.1 查询优化器的分类
· Top-down Optimizer
√ 从目标输出开始,由上往下遍历计划树,找到完整的最优执行计划
√ 例子:Volcano/Cascade ,SQLServer
· Bottom-up Optimizer
√ 从零开始,由下往上遍历计划树,找到完整的执行计划
√ 例子:System R,PostgreSQL,IBM DB2
· Rule-based optimizer (RBO)
√ 根据关系代数等价语义,重写查询
√ 基于启发式规则
√会访问表的元信息(catalog),不会涉及具体的表数据(data)
· Cost-based Optimizer (CBO)
√ 使用一个模型估算执行计划的代价,选择代价最小的执行计划
2.2.1 RBO -关系代数
· 运算符:Select (σ) ,Project (π) ,Join (▷◁ ) ,Rename (ρ) ,Union (∪)等
· 等价变换:结合律,交换律,传递性
优化前:数据库 / 表 (笛卡尔积)--> 限制笛卡尔积 --> 限制笛卡尔积结果 --> 选列表(列信息)
2.2.2 RBO -优化原则
· Read data less and faster (I/O):输入优化,读少,快
· Transfer data less and faster (Network):网络传输少,快
·
Process data less and faster (CPU & Memory):CPU指令少 ,内存需求少
2.2.3 RBO -列剪裁
从上往下扫描,依次往下传递
2.2.3 RBO -谓词下推
2.2.4 RBO -传递闭包
2.2.4 RBO -Runtime Filter
2.2.5 RBO -小结
· 主流 RBO实现一般都有几百条基于经验归纳得到的优化规则
· 优点:实现简单,优化速度快
· 缺点:不保证得到最优的执行计划
顺序比随机更快
√ 单表扫描:索引扫描(随机I/O) vs.全表扫描(顺序I/O)
√ 如果查询的数据分布非常不均衡,索引扫描可能不如全表扫描√Join的实现:Hash Join vs.SortMerge Join
√ 两表 Hash Join:用小表构建哈希表——如何识别小表?
√多表Join :
√ 哪种连接顺序是最优的?√是否要对每种组合都探索?
√ N个表连接,仅仅是 left-deep tree就有差不多N!种连接顺序
√ e.q.N= 10->总共3,628,800个连接顺序
2.3 CBO概念
· 使用一个模型估算执行计划的代价,选择代价最小的执行计划
√ 执行计划的代价等于所有算子的执行代价之和
√ 通过RBO得到(所有)可能的等价执行计划
· 算子代价:CPU,内存,磁盘IO,网络IO等代价
√ 和算子输入数据的统计信息有关∶输入、输出结果的行数,每行大小...
√ 叶子算子Scan:通过统计原始表数据得到
√ 中间算子:根据一定的推导规则,从下层算子的统计信息推导得到
√ 和具体的算子类型,以及算子的物理实现有关
√ 例子:Spark Join算子代价= weiaht * row count + (1.0 - weight)* size
(如CPU代价+I/O代价)
graph TD
统计信息+推导规则 --> 计算算子代价--> 计算执行计划代价-->执行计划枚举
2.3.1 CBO统计信息
· 原始表统计信息
√ 表或者分区级别:行数、行平均大小、表在磁盘中占用了多少字节等
√ 列级别: min、max、num nulls、num not nulls、num distinct value(NDV)、histogram 等
· 推导统计信息
√ 选择率( selectivity ):对于某一个过滤条件,查询会从表中返回多大比例的数据
√ 基数( cardinality ):在查询计划中常指算子需要处理的行数
· 信息收集方式
√ 在DDL里指定需要收集的统计信息,数据库会在数据写入时收集或者更新统计信息
√ 手动执行explain analyze statement,触发数据库收集或者更新统计信息
√ 动态采样
2.3.2 CBO执行计划枚举
· 单表扫描:索引扫描(随机I/O) vs.全表扫描(顺序I/O)
√ 如果查询的数据分布非常不均衡,索引扫描可能不如全表扫描
· Join的实现: Hash Join vs.SortMerge Join
· 两表Hash Join
· 多表Join :
√ N个表连接,仅仅是left-deep tree就有差不多N!种连接顺序
√ e.g.N= 10->总共3,628,800个连接顺序
通常使用贪心算法或者动态规划选出最优的执行计划
2.3 CBO小结
· CBO使用代价模型和统计信息估算执行计划的代价
· CBO使用贪心或者动态规划算法寻找最优执行计划
· 在大数据场景下CBO对查询性能非常重要
3.社区开源实践
概览如下:
3.1 社区开源实践-Apache Calcite概览
· One size fits all:统一的SQL查询引擎
· 模块化,插件化,稳定可靠
· 支持异构数据模型
√ 关系型
√ 半结构化
√流式
√ 地理空间数据
· 内置RBO和CBO
3.2 社区开源实践-Calcite RBO
· HepPlanner6516
√ 优化规则( Rule )
√ Pattern:匹配表达式子树
√ 等价变换:得到新的表达式
√ 内置有100+优化规则
√ 四种匹配规则
√ARBITRARY/DEPTH_FIRST:深度优先
√TOP_DOWN:拓扑顺序
√BOTTOM_UP:与TOP_DOWN相反
√ 遍历所有的rule,直到没有rule可以被触发
√ 优化速度快,实现简单,但是不保证最优
3.3 社区开源实践-Calcite CBO
· VolcanqPlanner
√ 基于Volcano/Cascade框架
√ 成本最优假设
√ Memo:存储候选执行计划
√ Group:等价计划集合
√ Top-down动态规划搜索
√ 应用Rule搜索候选计划
√ Memo
√ 本质:AND/OR graph
√共享子树减少内存开销
√ Group winner :目前的最优计划
√ 剪枝(Branch-and-bound pruning):减少搜索空间
√ Top-down遍历:选择winner构建最优执行计划
3.4 小结
· 主流的查询优化器都包含RBO和CBO
· Apache Calcite是大数据领域很流行的查询优化器
· Apache Calcite RBO定义了许多优化规则,使用pattern 匹配子树,执行等价变换
· Apache Calcite CBO基于Volcano/Cascade框架
· Volcano/Cascade的精髓:Memo、动态规划、剪枝
4.前沿趋势
4.1 前沿趋势-概览
4.2 前沿趋势-DATA + AI
· AI4DB
√ 自配置
√ 智能调参(OtterTune,QTune )
√ 负载预测/调度
√ 自诊断和自愈合:错误恢复和迁移
√自优化︰
√统计信息估计( Learned cardinalities)
√代价估计
√学习型优化器(IBM DR2IEO)
√索引/视图推荐
· DB4AI
√ 内嵌人工智能算法(MLSQL,SQLFlow)
√ 内嵌机器学习框架(SparkML,Alink , dl-on-flink)
4.3 小结
· 大数据创业如火如荼,SQL查询优化器仍然是必不可少的一个重要组件
· 引擎架构的进化、云原生、湖仓一体等对SQL查询优化器有新的要求和挑战
· AI加持,学习型查询优化器在不断进化