spark-3.0.1源码阅读之流处理


  Spark的流处理从2.0开始就使用结构化流处理的模式,之前的微批处理模式已经不在跟新了,只是为了向后兼容,目前还保留着.
  结构化的流处理模式的处理速度为1ms,而微批的处理模式为100ms,时间相差100倍,本文就围绕解答为什么会有这100倍的差距展开解析.

1 spark流处理框架简要说明

1.1 微批处理方式

  Spark在2.0之前采用微批的处理模式,该模式把短时间内的数据作为批次,在此基础上进行计算.
  此模式的计算有较多缺陷,关于这些不足已有很多资料进行了解释,这里不再详述.

1.2 结构化流处理方式

  该方式是目前主要的计算方式,最大的特点是基于sql的操作,把每条数据插入一张无限大的表中,简单说就是执行类似insert语句,并在此条数据的基础上进行计算.
  此种方式的效率很高,比微批模式要快很多,主要还是采用了基于sql的计算,那么接下来会介绍一下spark sql 和mysql sql的对比.

2 spark sql VS mysql sql

  两者相同的地方都是解析sql并执行,下面从解析和执行两个层面来对比说明一下这两者的sql的相同和不同之处.
  Spark对sql的解析是借助antlr4这个语法分析器完成的,把sql最终分解为rdd的操作来执行,mysql使用自带的解析器来完成解析,把sql最终分解为指令来完成解析.

2.1 mysql的sql解析和执行

  Msyql的sql解析器把sql语句首先解析为一颗语法数,之后再进行合法性的检查,没问题后由优化器把语法树转化为最优执行计划,此处执行计划只是一个数据结构,具体可认为是指令树,然后交由存储引擎按照这个指令树逐步执行,最后把结果返回.
  可见,mysql的sql解析执行主要有下列步骤:
  1 解析器解析为语法树
  2 优化器把语法树转为指令树
  3 存储引擎顺序执行指令树得到结果

2.2 spark的sql解析和执行

  Spark对sql的解析是借助antlr4这个语法分析器完成的,首先得到逻辑执行计划,类似于mysql的语法树,再把逻辑执行计划分解映射到rdd的操作上,最后执行这些操作.
  可见,spark的sql解析执行主要有下列步骤:
  1 生成逻辑执行计划
  2 转为rdd操作
  3 执行操作

2.3 小节

  Spark的sql解析和执行和mysql的解析执行大致相同,可以认为mysql的语法树对应spark的逻辑执行计划,mysql的指令树对应spark的rdd操作集,mysql的存储引擎顺序执行指令对应spark的直接执行rdd操作.

3 调试的代码

  Spark的流处理有很多类,这里组合两个测试类的代码,分别是org.apache.spark.examples.sql.streaming的StructuredNetworkWordCount和org.apache.spark.sql.streaming.continuous的ContinuousSuite类,第二个是测试目录中的类,把第一个类的代码拷贝到第二个类的test(“query without test harness”) 方法中,把源代码注释掉,之后再反过来操作,目的就是为了对比.
在这里插入图片描述

4 结构化流飞快的原因分析

  进入最后一个start方法,此方法的调用树为
在这里插入图片描述

  重要方法startQuery的调用树为
在这里插入图片描述

  重要方法createQuery,进入此方法,可以看到对(sink, trigger)进行了判断
在这里插入图片描述
  这里就是重要的分水岭,两个重要的类ContinuousExecution和MicroBatchExecution,这两个类就对应着结构化流处理和微批处理两种模式.

4.1 ContinuousExecution类解析

  ContinuousExecution继承自StreamExecution类,该类是虚类,但只用一个虚方法runActivatedStream
在这里插入图片描述

  所以ContinuousExecution复写了该方法,进入该方法,其调用的方法树为
在这里插入图片描述
  重要方法为runContinuous,其调用的方法树为
在这里插入图片描述

  重要方法SparkPlan的execute方法,其调用树为
在这里插入图片描述

  重要方法为doExecute,此方法被很多rdd的操作复写了,这里以join的操作为例,来看一下其主要操作都有哪些
在这里插入图片描述
  SortMergeJoinExec复写的doExecute方法调用的方法很多,其调用的方法树为
在这里插入图片描述
  这些方法进去后就能看到都是rdd的直接或间接操作,所以不论是什么执行的类,复写的doExecute都是直接或间接的rdd操作.
  因此可以看到,在结构化流的执行过程中,进行到SparkPlan的execute方法就是最后一步要执行rdd操作的方法了.

4.2 MicroBatchExecution类解析

  和ContinuousExecution一样,MicroBatchExecution也继承自StreamExecution类,只复写了唯一的虚方法runActivatedStream,进入该方法,其调用方法树为
在这里插入图片描述

  重要方法为runBatch,其调用的方法树为
在这里插入图片描述

  重要方法为getBatch,其调用的方法树为
在这里插入图片描述

  这个Dataset的方法ofRows,其调用的方法树为
在这里插入图片描述

  可见,调用了executePlan方法,执行计划,但是此计划是逻辑执行计划,从它的输入参数是 LogicalPlan的实例就能看到.

4.3 原因分析

  通过对上述两个类ContinuousExecution和MicroBatchExecution的分析,可以明显的看到,最重要的区别就是:
  1 ContinuousExecution每次执行的都是针对每条数据的rdd操作
  2 MicroBatchExecution每次执行的都是逻辑执行计划
  这就相当于mysql的缓存命中和每次都执行一次sql语句的差别.结果显而易见,时间上相差100倍也不足为奇了.

5 结论

  Spark使用结构化流处理把数据的处理速度大幅提升了,借助sql引擎,每次都相当于只执行针对一条数据的计算,这比之前每次都要执行一遍逻辑执行计划要快得多,主要结论有:
  1 spark的流处理基于sql引擎
  2 spark的sql和mysql的sql在解析和执行上的逻辑基本相同,设计和实现也大同小异
  3 spark的结构化流处理时间为1ms,可以和flink相提并论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值