Spark Sql优化器引擎-CataLyst

Catalyst的工作流程:

  • Unresolved Logical Plan:
    • SQL语句首先通过sql parser模块被分词, 形成select, where ,join等语句块, 并将这些语句块行成语法树. 此棵树称为Unresolved Logical Plan
  • Logical Plan:
    • 借助表的元数据将Unresolved Logical Plan解析为Logical Plan.
    • 例如, 上一步的逻辑执行框架有了基本骨架后, 系统并不知道tableA包括什么列, 列的数据类型, 表的数据格式(text,orc), 表的物理位置, sql中的函数指的哪个类等等; 这些在信息都保存在标的元数据中, 同时也能判断sql语句的正确性
  • Optimized Logical Plan:
    • 通过RBO, 将Logical Plan优化为Optimized Logical Plan
    • 这步优化器是Catalyst最重要的部分(Optimizer类), RBO-指基于规则的优化, 规则有很多种, 常见的有如下3种:
      • 谓词下推:
        比如一个sql:
      select * from A join B on 条件1 where B.age>10;
      
      由于数据量的大小会显著影响join的效率, 因此, 通过谓词下推把join放在where的后面执行. 先用where条件缩小表B的量, 再进行join
      • 常量累加:
        比如一个sql:
      select x+1+2;
      
      查询列会被优化成x+3, 虽然改动很小, 但是优化后每次操作都不会再去执行1+2这个动作
      
      • 列值裁剪
        有的sql语句可能并不会使用到一个表的所有列, 此时只需要用标的部分列参加运算即可, 这尤其在列式存储的表中大大提高扫描性能(减少网络内存的数据量消耗)
  • Physical Plan:
    • 得到的Optimized Logical Plan并不能被spark所理解, 此时需要转换为Physical Plan
    • 比如join算子, spark并不知道使用BroadcastJoin, 还是ShuffleHashJoin,还是SortMergeJoin; 物理执行计划就是在这些具体实现中跳出一个耗时最小的算法实现, 这个过程涉及基于代价的优化CBO. join通常有两个选择题要做
      • 一个是上面说的选择哪种join算法
      • 另一个是join的顺序选择
        对于星型模型和雪花模型来讲, 不同的join顺序意味着不同的执行效率. 例如
        A join B join C
        
        A,B表都很大, 但是C表很小, 则AjoinB显然需要大量的系统资源完成; 如果使用'A join C join B'的顺序执行, 因为C很小, 所以A join C会很快得到结果; 而小的结果集再去join B, 性能会显而易见的比前一种方案好. 而这种join顺序的选择, 并没有一个固定的规则来完成, 只有知道表的基础信息(表的大小, 表的记录总条数), 才能从中选择一条代价最小的语法树来执行. 即CBO的核心在于评估处一条给定语法树的实际执行代价

CBO的实现思路

  • 采集原始表的基本信息
    这个操作是CBO最基础的一项工作,采集的主要信息包括表级别指标和列级别指标,如下所示,estimatedSize和rowCount为表级别信息,basicStats和Histograms为列级别信息,后者粒度更细,对优化更加重要。
    • estimatedSize: 每个LogicalPlan节点输出数据大小(解压)
    • rowCount: 每个LogicalPlan节点输出数据总条数
    • basicStats: 基本列信息,包括列类型、Max、Min、number of nulls, number of distinct values, max column length, average column length等
    • Histograms: Histograms of columns, i.e., equi-width histogram (for numeric and string types) and equi-height histogram (only for numeric types).

这些指标是一些统计指标, 因此需要单独执行统计, 最好在业务低峰期, 对表数据有较大的变化的表单独统计. hive通过analyze命令对表的数据信息进行统计

  • 定义核心算子的基数推导规则
    假如sql中有where条件语句"where cid>N", 如何推导出经过这个条件过滤后的中间表的基本统计信息?
    第一步的原始表基本信息中, 其中有一项是列值分布的Histograms(直方图), 可以从直方图中粗略找到cid大于N的记录有多少条
    <img src="img/cbohistogram,png.png">

  • 核心算子实际代价计算
    通常来讲,节点实际执行代价主要从两个维度来定义:CPU Cost以及IO Cost。为后续讲解方便起见,需要先行定义一些基本参数:

    • Hr:从HDFS上读取1byte数据所需代价
    • Hw:往HDFS上写入1byte数据所需代价
    • Tr:数据总条数(the number of tuples in the relation )
    • Tsz:数据平均大小(Average size of the tuple in the relation )
    • CPUc:两值比较所需CPU资源代价(CPU cost for a comparison in nano seconds )
    • NEt:1byte数据通过网络在集群节点间传输花费代价(the average cost of transferring 1 byte over network in the Hadoop cluster from any node to any node )
    • ……

    上文说过,每种算子的实际执行代价计算方式都不同,挑两个比较简单、容易理解的来分析,第一个是Table Scan算子,第二个是Hash Join算子。

    • Table Scan算子
      直观上来讲这类算子只有IO Cost,CPU Cost为0。Table Scan Cost = IO Cost = Tr * Tsz * Hr,很简单,Tr * Tsz表示需要scan的数据总大小,再乘以Hr就是所需代价。OK,很直观,很简单。
    • Hash Join算子
      以Broadcast Hash Join为例(小表构建hash桶,大表负责探测),假设大表分布在n个节点上,每个节点的数据条数\平均大小分别为Tr(R1)\Tsz(R1),Tr(R2)\Tsz(R2), … Tr(Rn)\Tsz(Rn),小表数据条数为Tr(Rsmall)\Tsz(Rsmall),那么CPU代价和IO代价分别为:
      • CPU Cost = 小表构建Hash Table代价 + 大表探测代价 = Tr(Rsmall) * CPUc + (Tr(R1) + Tr(R2) + … + Tr(Rn)) * N * CPUc,此处假设HashTable构建所需CPU资源远远高于两值简单比较代价,为N * CPUc
      • IO Cost = 小表scan代价 + 小表广播代价 + 大表scan代价 = Tr(Rsmall) * Tsz(Rsmall) * Hr + n * Tr(Rsmall) * Tsz(Rsmall) * NEt + (Tr(R1)* Tsz(R1) + … + Tr(Rn) * Tsz(Rn)) * Hr
  • 选择最优执行路径(代价最小的执行路径)
    通常使用动态规划, 从各种执行路径中找出代价最小的执行路径

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容