漫谈分布式系统 (20):基于规则的优化

栏目: IT技术 · 发布时间: 4年前

内容简介:这是《漫谈分布式系统》系列的第 20 篇,预计会写 30 篇左右。每篇文末有为懒人准备的 TL;DR,还有给勤奋者的关联阅读。扫描文末二维码,关注公众号,听我娓娓道来。也欢迎转发朋友圈分享给更多人。前面几篇文章,我们讲到,MapReduce 和 Spark 在引入 SQL 之后,诞生了 Hive 和 Spark SQL,大大提升了开发性能。

这是《漫谈分布式系统》系列的第 20 篇,预计会写 30 篇左右。每篇文末有为懒人准备的 TL;DR,还有给勤奋者的关联阅读。扫描文末二维码,关注公众号,听我娓娓道来。也欢迎转发朋友圈分享给更多人。

细节是负担,甩掉有代价

前面几篇文章,我们讲到,MapReduce 和 Spark 在引入 SQL 之后,诞生了 Hive 和 Spark SQL,大大提升了开发性能。

然后又讲到,受 Shuffle 性能优化的启发,对 SQL Join 的性能做了一些优化。

在讲 Join 性能优化的时候,虽然我没明说,但也能隐约感觉到一个不好的趋势。

那就是, SQL 这种声明式的语言,通过隐藏实现细节,减轻了开发成本。但也同样因为隐藏实现细节,失去了主动优化性能的可能

一条 SQL 性能的好坏,很大程度上,已经不受开发者的控制了。

这样也没错,毕竟开发者的水平参差不齐,都去手写 MR 和操作 RDD,肯定有人能写的性能很好,但大部分人恐怕都需要花非常多的时间去积累经验。

所以, 把性能优化的主动权交给 SQL 引擎,再集思广益,把常见的优化经验都统一实现掉,也不失为好的选择

细节是负担,甩掉有代价。但我们可以用经验来弥补这个代价

在 SQL 里,这些经验被总结为规则,这一类性能优化操作在查询优化器(Query Optimizator)里完成,也就是我们今天要讲的 基于规则的优化(Rule Based Optimization) ,简称 RBO

向旧技术取经

一个很现实又略显沮丧的事实是,计算机界尤其是互联网界的很多所谓新东西,都只是旧技术和新场景的组合,再套上个炫酷的名字而已,所谓新瓶装旧酒

虽然要解决很多我们前面文章讲过的问题,但分布式领域的 SQL,本质上也只是传统关系数据库的 SQL 在多机扩展下的实现而已。

但幸运的是,这也意味着,在传统关系数据库库里已经积累了很多年的经验,也可以继续在分布式 SQL 里用到。包括 RBO

漫谈分布式系统 (20):基于规则的优化

上图是 Oracle 支持一些的 RBO Path。Oracle 会对查询语句按照支持的规则去解析和匹配,然后选择优先级最高的执行,编号越小,优先级越大。

以 Path 1 和 Path 15为例。当我们通过 Rowid 查询一条数据时,由于主键有索引,显然走索引会比全表扫描要快的多,因此会自动选择 Path 1 而不是 Paht 15。

只要把这些久经考验的规则依葫芦画瓢实现一遍,分布式下的 SQL 就有了基础了 RBO 了。

下面看下我们前面重点关注的 Hive 和 Spark SQL 的情况。

既然 RBO 是个非常套路固定的东西,而 Hive 作为 Apache 开源项目的代表之一,就没有选择造轮子,而是使用了著名的 Apache Calcite 作为优化器(包括下一篇要讲的 CBO)。关于 Calcite,我之前写过几篇文章,链接会贴在文末,这里就不重复了。

下面这张图,我截取了部分目前 Calcite 支持的 rules,感兴趣的可以自己去看实现,具体对应的是 Calcite 的 HepPlanner 和 org.apache.calcite.plan.hep 包。

漫谈分布式系统 (20):基于规则的优化

而对于 Spark,我前面的文章也说过,Spark 是个非常有野心的项目。所以并没有直接用现成的 Calcite,而是造了个叫 Catalyst 的轮子。

在 Spark SQL 的 org.apache.spark.sql.catalyst.optimizer.Optimizer 类中,可以看到也定义了很多规则:

漫谈分布式系统 (20):基于规则的优化

有了这些规则,Hive 和 Spark SQL 就能实现非常多的常见优化了,最基本的性能保证就有了,再差的新手写出的 SQl,性能也有底线了。

规则是怎么生效的

从编译原理中我们知道,一个 parser 对一段程序处理后,会输出一个抽象语法树(AST)。SQL 也是一门语言,最终要编译成底层执行引擎能处理的样子。

所以 RBO 的大致过程可以理解为, 通过应用不同规则,对 AST 做等价转换

上篇刚讲过 join,那就一起看一个 join 的例子,搭配一个最常规的规则 -- 谓词下推(Predict Pushdown)。

首先,有这么两张表:

create table user(id int, name string);

create table order(id int, uid int, item_id int);

查询语句是这样:

select

u.id as user_id, u.name as user_name, o.id as order_id

from

user u

join

order o

on

u.id = o.uid

where

u.id > 100;

初始解析完的执行计划,是先扫描两张表,然后 join 匹配数据,最后过滤出 u.id > 100 的数据。

而谓词下推,顾名思义,就是把判断条件下推到存储引擎,提前过滤掉不需要的数据,这样就能大幅提升性能。

画成示意图是这样:

漫谈分布式系统 (20):基于规则的优化

我们用 explain 语句,来看下实际的执行计划。

在 Hive 里是这样,可以看到,两张表都先做了 Filter 操作,然后才 Join。

漫谈分布式系统 (20):基于规则的优化

下面这个 Spark SQL 的图看的更清楚。

漫谈分布式系统 (20):基于规则的优化

在 Analyzed Logical Plan 里,是在 Join 之后才 Filter。而经过优化后的 Optimized Logical Plan 里,就变成了分别先对两表做 Filter,然后再 Join。

类似 Predicate Pushdown 这样简单又实用的规则还有很多,常见的比如 Projection Pushdown,会在扫描表的时候就把不相干的列去掉;Filter Combine 会把多个 Filter 合并之后再去过滤,等等,限于篇幅,就不再举更多的例子了。

这样,通过对一系列规则的应用,不断地对 AST 做等价转换,直至找出最优的逻辑计划。然后就可以转换成物理执行计划,交给执行引擎去处理了。

RBO 的局限性

RBO 能发挥非常不错的优化效果,是因为汇集了大量经验,并具象化为一条条可执行的规则

但也正是这些规则,导致了 RBO 的局限性

因为规则是死的:

  • 规则无法穷举,虽然可以逐步完善(人是活的),但总有覆盖不到的点,

  • 规则可能矛盾,各自独立的规则,不会考虑和其他规则的关系,一旦矛盾,就很难取舍,

  • 规则很难确定优先级,先应用哪个后应用哪个,可能产生不一样的优化效果,

  • 规则对不同的数据可能产生差距巨大的效果,

  • ......

举一个例子,我们都知道一个很简单的规则,如果一个列建了索引,当以这个列为查询条件时,应该走索引,而不是全表扫描。

但是,看这样一种情况,有一张公司人员表,其中有个建有索引的字段 gender。现在要查询男性员工的地区分布,但是这个公司是个做苦力的工厂,超过 90% 的员工都是男性。那这个时候先查索引找到所有男性员工,再去查地区分布,性能就远不如直接全表扫描了。

很显然,RBO 并不能解决所有性能优化问题,甚至可能帮倒忙。

究其根本原因, 任何规则 -- 不仅是 SQL 优化里的规则 -- 作为经验的积累,都必然不能解决所有问题。因为经验是人对事物共性的归纳,在归纳的过程中必然存在样本不足、信息损耗和过度拟合的情况。这是经验的局限性,在表象上的体现,就是不灵活或者有时候失灵了

TL;DR

这篇文章,我们粗略了解了基于代价的优化是怎么一回事,简单提炼要点如下:

  • SQL 通过隐藏实现细节,提高了开发效率,但也失去了主动优化性能的可能,

  • 好在有些通用的性能优化手段,可以统一实现,即所谓基于规则的优化(RBO),

  • Oracle 等传统关系数据库已经积累了非常丰富的 RBO 经验,分布式 SQL 只需要照做即可,

  • RBO 本质上就是通过应用规则,对 AST 做等价变换,直至找出最优计划,

  • 但 RBO 是基于经验的,而任何经验都是有缺陷的,如对不同的数据内容会产生悬殊的结果。

所以,我们需要另外的思路,来继续 SQL 性能优化。 另一种不像 RBO 这样间接归纳的思路,另一种更加直接却又灵活的思路

下一篇,我们一起了解下基于代价的优化(CBO)。

原创不易

关注/分享/赞赏

给我坚持的动力

漫谈分布式系统 (20):基于规则的优化

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

维多利亚时代的互联网

维多利亚时代的互联网

[英] 汤姆·斯丹迪奇 / 多绥婷 / 后浪丨江西人民出版社 / 2017-8 / 38.00元

人类历史上的第一次大连接 回顾互联网的前世 预言互联网的未来 ……………… ※编辑推荐※ ☆《财富》杂志推荐的75本商务人士必读书之一 ☆ 回顾互联网的前世,颠覆你的思维,升级你对互联网的认知 ☆ 人类历史上一次全球大连接是维多利亚时期的电报时代,那时候也有疯狂的资本、 巨大的泡沫、网络新型犯罪、网络亚文化崛起……现在的互联网时代就是电报时代的重演;回顾那......一起来看看 《维多利亚时代的互联网》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

html转js在线工具
html转js在线工具

html转js在线工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具