第十章:spark streaming 流数据处理框架
一。spark streaming程序的几个步骤
1.创建StreamingContext。sparkstreaming context和spark context创建区别不大,唯一要加的就是streaming context需要添加一个Seconds(1),指定处理数据的时间间隔。就是batchDuration,而且该处理间隔一旦设定就没法改变。1就是为每隔一秒处理一次数据。
2.创建InputDStream
如果storm的spout,sparkstreaming也需要指明数据源。比如socketTextStream将用套接字作为数据源读取数据。同时也支持kafkaStream,flumeStream,fileStream,networkStream,mqttStream,zeroMQStream
3.操作Dstream
Dstream是包含了一系列的RDD,这些RDD可以从数据源来,也可以从转换操作来。比如对从数据源得到的数据首先进行分词,然后利用mapreduce算法映射和计算、最后用print()输出结果。
4.启动Spark Streaming
当ssc.start()启动后,程序才真正开始进行所有预期的操作。
二。spark streaming基本概念
1.滑动间隔和窗口间隔都是批处理间隔的整数倍,窗口间隔是有重合的,但是spark保证了处理不会重复。
2.DStream的操作最终还是要通过RDD的操作来实现,不过是DStream提升了抽象程度,隐藏了具体的实现细节。
3.DStream操作函数
repartition(num) 改变DStream的分片数量
union(otherStream)跟其他的stream合并。
count()返回原DStream中各个RDD中元素的个数。
reduce(func)
reduceByKey(func)按照key对元素通过func进行聚合,本地环境并行度是2,集群环境并行度是8
join() 原来是DStream[(k,v)] 变成DStream[(k,(v,w))]
等等 p236页
三。性能调优
1.运行时间优化
增加并行度。把任务分散到多个节点上,特别是含有shuffle的操作
减少序列化负担,spark默认对接收到的数据是序列化存储,减少内存,所以使用自定义的序列化方式或者更搞笑的序列化方式更好。
设置合理的批处理间隔,若在间隔范围内没处理完,这就不好了,后面会不断堆积
减少任务提交和分发带来的负担,如果批处理时间间隔小的话,会不停的进行任务提交和分发,就不太好。
2.内存使用优化
控制批处理间隔数据量,过大处理起来,内存会存不下
及时清理不用的,最好是spark.streaming.unpersist()设置为true,可以自动回收。
观察和调整GC
四,容错
通过rdd的依赖关系进行恢复。能从原始数据集中恢复出来。所有中间结果都是可被计算的。
工作节点失效。数据源不丢失,就不会丢失。
驱动节点失效。从断点继续读取,启动时指定StreamingContext.getOrCreate,记录点记录的数据是类序列化后的结果,因此若重新编译代码后反序列化就会出错。
五。DStream作业的产生和调度
spark中,作业是由一系列有继承关系的RDD和作用在其上的函数所组成的完整的操作链。并由输出RDD向DAGScheduler提交操作链来提交作业。
spark是按照输出操作来判断作业产生的,有多少个输出就有多少个作业。作业内或许有依赖,这些作业会注册到DStreamGraph中等待提交执行。
作业调度是在每个批处理间隔的时间点到来,注册在DStreamGraph中的作业会被取出来放进JobScheduler进行调度和提交。
a.sparkStreaming内部维护了周期性的定时器,超时间隔就是预先设置的批处理间隔。超时后就请求DStreamGraph来产生streaming作业
b.JobScheduler内部维护线程池来运行作业。默认是1,可以通过concurrentJobs来配置。
c.最终从Graph中得到的作业还是转换成spark作业来处理,通过spark的spark scheduler来处理。
六。DStream和RDD的关系。
DStream内部可以分为下面三个部分。
1.一组基于操作链的依赖关系。就是该DStream所依赖的父DStream
2.批处理间隔
3.一个计算RDD的函数compute()。getOrCompute()函数会在其内部递归调用操作链上的所有的DStream的compute函数,来获得新的RDD,该RDD就是记录了完整的执行任务的操作链。啊
二。时间和窗口概念
sparkStreaming系统要等到数据汇总到一定的量后再一并操作,这个间隔就是批处理间隔。决定了提交作业的频率和数据处理的延时,同样也影响着数据处理的吞吐量和性能。
2.1滑动间隔(slide duration)和窗口间隔(window duration)
这两个间隔都是批处理间隔的整数倍,处理数据的间隔取决于滑动间隔,所使用的数据量是窗口间隔来决定的。从字面意义上来说,滑动间隔其实就窗口要开始滑动的时候,比如长度为四的窗口间隔,如果滑动间隔为2,那么在这四个批处理间隔内,会有两次的滑动操作,这两次的滑动操作中,会有两个批处理间隔的数据会重复的,但是sparkstreaming系统中做了优化,不会让重复计算发生,同时因为多次处理了很多数据,从而提升了处理速度。
2.2DStream 离散数据流
从英文意思上看,就是从多个分布式数据源中收集到的数据流,离散数据流DStream有三种操作,一种是普通的转换操作,一种是基于窗口的变换操作,一种是输出操作。转换操作不会产生和提交作业,只构成DStream操作链 比如flatmap,filter,count reduce等
窗口的变换操作,将转换操作和窗口操作合并后得到的操作 reduceByWindow reduceByKeyAndWindow,窗口操作会在其内部隐式的将DStream中的RDD持久化到内存中而无须用户显示的调用。
输出操作 foreachRDD saveAsTextFile
3.作业产生
操作链定义完成,提交到DAGScheduler后,就会产生作业了,一个作业有多少个输出就有多少个作业,作业之间可能会有依赖,会根据依赖关系来处理作业。
4.作业产生后也不会立刻提交,而是等到streamingContext启动后,在批处理间隔到来后才会真正的被执行。
三。streaming作业与spark作业之间的关系。
DStream在内部维护了相应的RDD,无论是转换操作还是输出操作,都会最终被映射到RDD上,因此sparkStreaming可以自然而然的产生与之一一对应的spark作业。当在构建DStream操作链时,spark内部就在构建RDD操作链,这个RDD操作链最终会在其内部产生作业并提交运行。最后用runJob()提交作业。