Spark分析(十三)Spark Streaming中Spark 2.X的流计算

Spark分析(十三)Spark Streaming中Spark 2.X的流计算,第1张

Spark分析(十三)Spark Streaming中Spark 2.X的流计算 2021SC@SDUSC 前言

上一篇博客分析了Spark Streaming的性能调优机制,这次分析一下Spark 2.X的流计算过程

介绍

Spark 发展迅速,如今最新的版本已经是3.X了,但由于分析的需要以及减少分析困难,我们小组选定的是3.1.2的版本(详见小组环境配置博客:山东大学软件工程应用与实践——Spark项目(一)),但本次分析不针对Spark3.X的流计算特性而转而分析Spark2.X中的内容,是为了便于为Spark进行理解。这里也结合databricks官方演示文档里的一些图片进行分析。

Spark流计算

Spark2.X中相比于Spark1.6.X之前的版本,其提出了包含三个主题的更新:Easier、Faster、Smarter。
Spark2.X将流式计算也统一到Dataframe里中,提出了Structured Streaming的概念。功能更强大,效率更高,与其他组件的整合性也更好。
Structured Streaming的核心是将流式的数据看成一张不断增加的数据表,这种流式的数据处理模型类似于数据块处理模型,你可以把静态数据库表的一些查询 *** 作应用在流式计算中,Spark运行这些标准的SQL查询,从不断增加的无边界表中获取数据。
不断输入的流式数据会被加载为内存中一张没有边界的数据表,每一条新来的数据都会作为一行数据新增到这张表中。

一、连续应用程序

首页,也是最重要的,在Spark2.X中提出了一个叫做连续应用程序(continuous application)的概念。
下图展示了一个围绕流数据展开的各种业务,数据从Kafka中流进来,通过ETL *** 作进行数据清洗,清洗出来作为目标数据进行进一步处理,可能是机器学习,也可能是交互式查询,也有可能直接把数据存在数据库或者其他外部存储设备,还有可能是直接交给已有的应用程序。

围绕流数据展开的多个端到端处理的连续应用程序

Spark 2.X把流数据看成是一个没有边际的表,并能把全部处理环节串联起来,形成端到端(end to end)处理。
而连续应用程序的模型就与这个类似,在充分应对风险的前提下,可以串联业务的全部过程。
下面的几行Scala代码就可以贯穿一个业务案例从始至终的业务流程。

logs = ctx.read.format("json").stream("s3://logs")

logs.groupBy("userid","hour").avg("latency").write.format("jdbc").startStream("jdbc:mysql//...")
二、无边界表unbounded table

对Spark Streaming来说连续(continuous)还有另一层含义,即运行在Dataset和Dataframe.之上。
基本观点是把数据看成一张表,默认情况下Dataset和Dataframer中的表是有边界的,而在流处理中是无边界的(unbounded)。对Spark Streaming来说,是将数据抽象为一个没有边界的表。没有了DStream,没有了先将数据收集过来再处理的概念。这个做法有一个非常大的好处。我们知道,目前Spark Streaming.直接依赖RDD,优化需要开发者自己完成,使用Dataset和Dataframe就可以利用Tungsten引擎来进行优化。默认情况下,Dataset、Dataframe是静态有边界数据(static bounded data),流数据是流式无边界数据(streaming unbounded data)。API把两者融合在一起,如下图所示。

Dataset/DataRrame API

如下图所示,新加入的Planner就类似路由器,我们在使用时,可以按照时间说明,由Planner确定每次读取的位置,在运行时动态绑定位置。在这种模式下,没有数据收集再处理的概念,可以认为数据一直在那儿,直接拿了处理就行。这可以极大地简化对流处理。

三、增量输出模式

在Spark 2.X中,增加了多个输出模式,增量输出(delta ouput) 是其中最重要的一种,如下图所示:

增量输出模式

增量更新,也就是说有需要更新的数据的才会更新,其他的不变。Trigger会不断检测输入数据,在不断地进行处理之后,输出结果只更新需要更新的内容,这个更符合应用程序的处理场景。

四、API简化

在API方面引入和流函数的封装。
这里举一个例子:Kafka中读取的数据,通过stream方法形成流,就可以直接与JDBC中读取的数据在Dataset层面进行join,不用transform或者foreachRDD方法。

kafkaDataset = spark.read.kafka("iot-updates").stream()

staticDataset = ctxt.read.jdbc("jdbc://", "iot-device-info")

joinedDataset = kafkaDataset.join(staticDataset, "device-type")

stream方法底层依赖Dataset和Dataframe,集成了Spark SQL和Dataset几乎所有的功能,把流处理的代码写一下简化了很多。

五、其他改进

Spark2.X同时也解决了DStream的很多问题:

  1. 增加了eventTime的概念,把原有基于mini batch 处理的基础上,学习了Storm基于每个record的事件处理机制。
  2. 可以把Spark Streaming抽象成一个数据库,直接通过JDBC访问数据。
  3. 在运行时可以变更query,并支持多个query并行运行。
总结

从Spark2.X的设计来看,从根本上,是为了满足更快、完全容错、完全的语义一致性exactly-once的要求。通过实现由状态流处理,让应用程序的功能更强大。而基于Dataset和Dataframe处理,让我们忘记流的概念,使用将会越来越简单。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5678802.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存