Spark Optimizer 规则下的 BUG 排查与修复全记录

本文作者:朱明亮,观远数据计算引擎开发工程师,13 年毕业于湖南大学,有七年多的大数据研发经验。曾就职于知名互联网公司数据研发专家岗位,负责打造服务公司内部各业务线的数据中台,是开源项目 byzer-lang(基于 Spark 的开源中台计算引擎)的主要贡献者之一。

背景

测试同学在内部环境测试发现一个严重的问题,ETL 执行结果不符合预期,根据 Rawdata Date 字段筛选 等于 2022-07-12 筛选出来的数据是 7.11 号的,直接筛选 2022-07-11 出来的数据是空的。

排查过程

1. 简化逻辑

ETL 流程过于庞大,首先需要花点时间简化 ETL,尽量最小化的复现出问题,利于排查。

简化的方法:

  • 如果 ETL 执行时间较长,首先缩减数据集的大小,可以 limit 之后保存新的数据集,用新的数据集进行测试。

  • 从头尾往中间缩减逻辑,直到不能复现问题。头部的缩减可以保存临时数据集,然后使用临时数据集进行计算,尾部的则直接预览上一个步骤的结果。

简化后的逻辑是两个数据集,一张 A 表,有日期类型字段 a,一张 B 表,有日期类型字段 a,b,用 sql 表示为:

select  to_date(a) as a, to_date(b) as b from 
(select to_date(a) as a, to_date(A)  as b from 
(select to_date(a) as a from A group by to_date(a)) t1
union all 
select to_date(a) as a, to_date(b) as b from B group by to_date(a), to_date(b)) t2
group by  to_date(a), to_date(b)

当然 job engine 得到的是脚本文件,这里写成 sql 更加直观看出逻辑,通过查看脚本,确定 BI 生成的逻辑是正确的,那问题是出在了 engine 层。

2. spark 本地复现排查

本地复现

将简化后的脚本转化为 spark 算子或者 spark sql,测试环境是 spark 3.2.1,在 spark 3.2.1 版本复现了该问题,本地复现后就便于去 debug 调试。

  test("test1") {
    val sqlText =
      """
        |select to_date(a) a, to_date(b) b from
        |(select  to_date(a) a, to_date(a) as b from
        |(select to_date(a) a from
        | values ('2020-02-01') as t1(a)
        | group by to_date(a)) t3
        |union all
        |select to_date(a) a, to_date(b) b from
        |(select to_date(a) a, to_date(b) b from
        |values ('2020-01-01','2020-01-02') as t1(a, b)
        | group by to_date(a), to_date(b)) t4) t5
        |group by to_date(a), to_date(b)
        |""".stripMargin
    spark.sql(sqlText).show()
  }

期待的结果:

a b
2020-02-01 2020-02-01
2020-01-01 2020-01-02

返回的结果:

a b
2020-02-01 2020-02-01
2020-01-01 2020-01-01

可以看出来,所有数据的 b 取了 a 的值,接下来就是查看 spark 执行计划。

执行计划

先简单介绍下 Spark Catalyst 优化器。

一条 SQL 语句生成执行引擎可识别的程序,就离不开解析(Parser)、优化(Optimizer)、执行(Execution) 这三大过程。而 Catalyst 优化器在执行计划生成和优化的工作时候,它离不开自己内部的五大组件,如下所示:

  • Parser:将 sql 语句利用 Antlr4 进行词法和语法的解析;

  • Analyzer:主要利用 Catalog 信息将 Unresolved Logical Plan 解析成 Analyzed logical plan;

  • Optimizer:利用一些 Rule 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值