Streaming Data Processing_11

回顾流式数据处理

1.流式数据作为今天各种应用所需要的一种新的处理方式,有它自己的一些特征,比如说秒级的这样一个反馈,比如说对数据能够在一个时间窗口里面进行一次的查看。

2.那么我们介绍了Hadoop生态环境下的Storm通过Tuple来在Spout和 Bolt之间进行一个数据的驱动方式的这样一个运行同时进行数据流的并行化,实际上它的模式是通过每一次产生新的Tuple,然后由Storm去驱动这些Tuple,在Bolt里面得到执行,并且产生数据的下一步的数据流。

3.那么我们在编写一个Bolt的过程中,我们已经体会到实际上在使用Bolt的时候,我们会被系统调起,
通过executor调起,然后我们会产生新的下一个这个数据的Tuple,然后来通知下一个Bolt运行。
实际上给人的感觉,它是一个被事件,被Action驱动的这样一个模式进行运行。

Spark Streaming_1

1.接下来介绍另外一个流式数据处理的框架 Spark Streaming,然后来介绍它在处理流式数据的时候,使用不同的一个思路。

2.在Spark Streaming里面,实际上它借用了之前,在Spark里面的若干的概念。那么我们回顾一下,在Spark里面,数据被变成了一个一个的RDD,然后RDD和RDD之间存在着转换的关系,然后可以通过RDD在内存或者是在磁盘得到一系列的存储和权限,这样一个方式。那么在Spark Streaming 里面,实际上也借用了这样一个方式,然后它在处理流式数据的时候,使用了一个转化处理的这样一个办法。我们有一个数据流,如果我们有办法将数据流变成一个一个的能够进行小规模批量处理的数据形态的话,实际上我们就可以完全利用原来的RDD的这样一个模式,那Spark Streaming就是基于这样的一个思路。

3.让我们来看怎么做的,我们有了一个数据流,我们希望做Spark Streaming的时候,我们会做一些什么样的事情呢?

3.1.我们不直接去处理这个实体流,或者是数据流中每一个很小的Tuple单元。相反,我们是把它变成了一个一个有一定程度的从时间上进行切片的数据块,它用了一个词,叫做chop。我们把这个数据流,把它切成了很多的这个数据片,每一个数据片的长度是可变的,比如说我们可以把它切成,按照每秒或按照每分或每几秒,把它切成一段一段的。那么这个每一段就变成了一个传统的RDD能够在Spark中得到处理,实际上根据不同应用的需求,我们完全可以控制切的数据块有多大,然后达到对延迟的一个控制,有了这样一个对数据进行一个小的batch的处理之后,实际上,原来在Spark里面提供到的Transform或者Action就都可以得到利用了,这是在Spark Streaming里面所做的事情。

3.2.在Spark Streaming最开始的这种实现当中,实际上他们已经可以做到秒级的一个数据延迟。同时呢,他们可以对这种很小的mini batch进行传统的RDD的操作。

4.在Spark Streaming里面,它是怎么去实现我们在Storm实现的这种容错性。

4.1.在Storm里面,因为依赖了和Hadoop类似的这种从中心到边缘,即从Nimbus到executor的管理,得到Supervisor这样的一个管理。那么我们来看,它在Spark Streaming里面,我们怎么样做到类似的Topology。实际上这部分的思路是比较简单的,因为在Spark里面,RDD本身是可以容错的,我们之前介绍过RDD,因为我们在整个系统中保存了RDD在执行的时候它的一系列操作的过程,它经过了什么样的Transform,然后最终如果某一个RDD缺失的话,我们可以通过Transform的log来达到一个恢复。在Spark Streaming里面,类似的思想也得到了一个使用。利用RDD它的一个特性,实际上我们在Spark Streaming里面也记录了它的一个执行的流程,那有了这样一个执行流程之后呢,实际上我们就可以通过某一个节点失败的时候,通过执行流程的一个重放来达到对它恢复的一个目的。数据经过一系列的Transform从RDD的一个状态变成另外一个新的RDD,然后新的RDD可以通过转换的过程来达到一个恢复。

4.1.1.那么在Spark Streaming里面尽管它是基于RDD,但是由于它的数据对象本身是一个Stream它引入了一些新的概念,第一个概念叫做DStream。

4.1.2.DStream是什么?

DStream是一系列时间序列产生的RDD的序列,这个序列可能是没有头也没有尾的,它是一系列的Mini的这种数据的batch,Mini的RDD。

4.1.3.那么这个数据流怎么来?

它可能会来自于我们刚刚说到的,这种社交媒体它产生的数据流,它可能是从其他的这种数据源生成的,比如说HDFS Kafka里面可以读出这样一个流式的数据。

5.Transform在Spark Streaming里面依然是实用的,它表示了从某一个Stream转换到另外一种Stream它的一个过程。它实际上继承了原来的RDD上Transform的一个概念,只不过现在我们可以从这个组成这个RDD,由这个RDD组成的Stream转换到另外一个新的形态的RDD就形成了另外一个Stream。实际上它的本质是在RDD上进行的。

6.然后我们有各种各样的输出的方式,在传统的Spark里面,实际上我们的输出通常是写到屏幕或者是我们存到分布式文件系统里面。那么在Spark Streaming里面,我们依然可以把它的一些结果输出到硬盘上,但是我们还有一些其他办法,我们可以让它产生新的一个数据流。我们可以让后面的处理Stream的Spark Streaming的任务可以进一步去做一些处理,然后我们可以让Spark Streaming也形成类似于Storm Topology那样复杂的结构在整个系统中。


小结

刚刚介绍了在Spark Streaming里面,它通过了一个什么样的办法来进行流式数据的处理,实际上它的思路很简单,也是我们处理流式数据很容易想到的一个思路。我们就是说怎么样把这个流给切成一个一个不是流数据,把它变成一个一个的小的batch,或者说大家爱叫做Mini batch的方式进行数据处理。那么通过这种方式,实际上它就可以很容易的去借用以前在RDD里面实现了各种各样的操作来进行这样一个数据的流式处理,那么引入了一个叫做DStream的概念。通过一系列的RDD Mini RDD组合在一起,形成了一个逻辑上的一个流。

Spark Streaming_2

1.Spark program vs Spark Streaming program

这里写图片描述

1).这张图对比了Spark Streaming里面的程序和Spark里面的程序。实际上我们发现它们几乎没有什么样的差别。

2).我们在Spark Streaming里面构建起一个叫做twitter这样一个DStream,这个Stream实际上来自twitter,它会把twitter最近发的这样一个数据变成一个一个小的Mini batch,然后每个小的RDD(Mini batch)形成了这样一个Stream,我们就可以在这个Stream上进行一系列的操作。实际上操作过程并没有我们刚刚说的那么复杂,那些Transform在实际的编码当中,可以把它直接应用到DStream上。我们发现它可以在刚刚的Stream twitter上进行flatMap,实际上它的意义是将flatMap应用到DStream包含的所有的RDD里面,这些小的RDD然后形成了新的Stream,叫做hashTags。这个flatMap,是把里面的一些关键词,通过了一个叫做getTags这样一个方法,把它里面的hashTag给拿了出来,我们不用去管这个函数具体怎么实现,大家现在需要知道它的功能就行了,然后这个hashTag就可以做进一步的操作。比如说,可以进一步的进行Transform,或者说现在我们把它保存在磁盘。

3).可以发现两段程序是非常非常相似的,也就是说在使用Spark Streaming进行数据操作的时候没有特别多的学习的成本,几乎可以把原来的Transform直接用过来,可能会有很小的语法上的调整而已,不像我们从MapReduce迁移到Storm的时候,整个思路要从Map和Reduce变成了Spout和Bolt的关系上。

2.Examples

那么我们来看在Spark Streaming里面实现了什么样的功能?可以供这个数据处理和开发人员进行真正的流式数据的处理。

下面给一些Spark官方教程里面的一些例子来帮助大家理解Spark Streaming的情况,大家可以进一步查找Spark Streaming最新的一些文档,来了解它最新的一些功能和feature。

Example 1 – Get hashtags from Twitter

第一个例子,就是刚刚已经给到大家了,怎么样从Twitter的Stream里面拿到hashTag?

1).我们创建了这样一个DStream(保存在变量tweets里),得到了现在Twitter上发的所有的这样一个流。DStream可以直接通过Spark Streaming里面已经提供的这些接口(API)来取得。它的图示,就是这样一个样子。

这里写图片描述

2).在不同的时间点,在你设定好时间窗口之后,不同的时间窗口就会产生不同的小的RDD,有了这些小的RDD之后,它会用到Spark这种分布化的对RDD的处理。之前介绍RDD的partition的时候,大家已经知道这些数据会到系统中的服务器上进行分布式处理,那么进一步我们去产生另外一个DStream,使用了原来的对应的这样一个Transform的方法,把它的hashTag给拿出来。拿出来之后呢,把它保存在新的DStream变量里面,这个过程实际上也是分布进行的。我们可以发现,在每个服务器上,它可能会对自己现在已经接收到了这个RDD进行独立的处理。因为这之间并没有特别多的数据的依赖,那么可以达到一个比较好的分布化的一个效果,形成了新的RDD。

这里写图片描述

3).形成新的RDD之后,我们可以对RDD进行进一步的处理。或者说,在我们目前的这个状态下,我们就想把它保存到磁盘。一样的,这个Spark Streaming会帮我们把数据分布的存储到磁盘里去。这样就完成了一个简单的第一个例子。

这里写图片描述

Example 2 – Count the hashtags

那么第二个例子,假设我们还想进一步去操作,我们想把这些hashTag给统计出来做一个计数。

1).实际上我们在原来的Spark也说到过类似的计数,比如说我们可以进行Reduce by k,我们把相同的k进行Reduce然后在Reduce里面对数据进行一个累加,可以完成这样的一个效果。

2).那我们来看,在Streaming的背景下怎么去做这件事情,刚刚我们说已经有了这一系列的命令的RDD,我们来看它的计数是怎么做的?我们使用了一个叫做CountByValue,实际上是把刚刚的DStream中那个RDD,它的value,就是它的hashTags进行一个Counts。它本质上是一个Reduce的操作,那么同样的,这些数据,每个RDD被Partition之后,会在各个Partition对应的Server上得到执行,得到计数,计数完成之后,会形成一个新的DStream,这个DStream,实际上就对应了你要统计的value,和统计value的数值。这是我们做到的对RDD进行类似于Reduce的操作。

这里写图片描述

Example 3 – Count the hashtags over last 10 mins

第三个例子我们加入了时间窗口

Description:现在我们并不关心从我们开启程序到现在所有时间的Count,我们关心的仅仅是最近十分钟,大家发出的Twitter的情况。比如说最近十分钟,什么样的hashTags是最流行的,那么我们就会加入这样一个时间窗口。

1).我们来看这个怎么做的,我们通过window这个新的Function,在传统的RDD里面没有这个东西。在Streaming里面,我们有了这个window,实际上window就是限制了当前的计算,它在一个什么样的时间范围内去做。那么也就是说在最近多少的RDD上去做,window有一个size概念,我们看的时间窗口有多大,十分钟,或者十秒钟。然后window往前移动的时候,它是怎么移动的,是不要相互覆盖呢,还是相互覆盖?那在这里面。我们给它移动的步长是一秒钟,也就是说它每次移动一秒,会有大量的和原来的窗口覆盖的空间,我们来看这个例子是什么样的。同样,先构造出window的操作,图片上已经给出了我们在不同的Mini batch里面,我们拿到的RDD的数据。当我们加入的窗口,是给定大小的window之后,那么我们就会只看这个window里面,它所产生的数据的统计。同样在这个window里面,我们可以做Reduce,或者我们可以做其他Spark已经给我们提供的操作,在这里我们进行了一个window里面的count,count出hash的数量。当我们window再往前移动的时候,我们参考了在window这个函数里面,我们指定的interval 步长,那么它会往前移动1,那么我们看下一个数据就可以被统计出来。

val tweets = ssc.twitterStream(<Twitter username>, <Twitter password>)
val hashTags = tweets.flatMap (status => getTags(status))
val tagCounts = hashTags.window(Minutes(10), Seconds(1)).countByValue()
//use window这个新的Function

这里写图片描述

这里写图片描述

2).如果只是简单的做刚刚的那样的计算的话,我们会发现,当窗口和窗口之间还有大量的重叠的时候,实际上我们浪费了很多的时间去做重复的操作,比如说加法,我们会反复的加很多已经被加过的数据。

3).在Spark里面,实际上有一个feature,它解决了这个问题,叫做Smart window,我们来看所谓的Smart到底是怎么做的呢,由于window这种操作,在大量这种流式数据处理里面会经常被常用。所以Spark针对这个情况做了一系列的优化我们来看这个Smart window怎么做的?和刚刚的例子一样,当我们指定一个window,计算window里面hashTag的count的时候,我们会做一个数据的叠加。而当window往前移动的时候,这时候我们在Smart window控制底下,我们并不需要去计算所有的数据,做重新的Reduce,重新的相加,我们仅仅是需要根据你做的操作的属性。

——比如说是加法,我们可以把移出窗口的元素,从刚刚的计算结果中减掉,然后加上我们后面窗口会包含进来的新元素。它在Reduce的背景下,产生的一个值,然后做一个增量式结果的迭代。实际上这种操作,当然大家能够体会得到,它并不是一个通用的,可能某些操作,你并不能做到Smart window这种操作。但是针对我们在Spark Streaming里面,所要处理的大量的数据,它都具有这种增量性。我们实际上,可以大大的通过Smart window的方法,来降低计算的开销。
这里写图片描述

4).那么在Spark Streaming里面实际上它的这种数据的状态,以及这种失败的保证,实际上它是通过数据本身,RDD本身来做到的。这和我们在Storm里面讲的不太一样,Storm里面,我们实际上把状态保存在节点上,它和我们运行这个Spout和Bolt的节点是相关的,一旦这个节点失败,可能它的状态会丢失。

5).那么这是在Storm这种由数据驱动,但是是由节点来保存状态信息的特性所决定的。在Spark Streaming里面,实际上这个问题得到了一定的克服,它的数据的状态实际上是保存在RDD里面,RDD和RDD,DStream和DStream之间,存在着一定的计算的关系,Transform的关系,而这种关系实际上刻画了它的状态。当一个DStream一旦生成之后,这个节点一旦失效了,也不会影响状态的记录,因为我依然可以通过之前的计算过程,对数据进行恢复。有了这样一个特性之后,实际上在Spark Streaming里面,它就可以基于这样的特性,进行更加鲁棒或者是更加高效的一个系统的可扩展性的一个构建,那这是Spark Streaming的一个优势。

Ends

希望童鞋们在真实的平台,不管是基于你自己的一个模拟的环境,或者是Cloud上的各种各样的Spark的平台上,大家能够去测试一下。把Spark原有的命令,原有的方法使用到Spark Streaming里面,然后来体会到Spark Streaming的一个优势;同时我们也鼓励大家对Spark Streaming和Storm,进行一个对比性的实验,大家来思考一下,除了我们讲到的这些特性以外,它们俩还会有什么样的差别联系。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值