流计算概述
流数据是指在时间分布上和数量上无线的一系列动态数据集合。数据记录是流数据的最小组成单元。
流数据特征
- 数据快速持续到达,无穷无尽
- 数据来源众多,格式复杂
- 数据量大,不关心存储
- 注重数据的整体价值,不过分关注个别数据
- 数据顺序颠倒或者不完整
流计算
流数据被处理后,一部分进入数据库成为静态数据,其他部分则直接被丢弃。流数据必须采用实时计算,实时得到结果。
流计算平台实时获取不同数据源的数据,经过实时分析处理,得到有用的信息。
Spark Streaming
Spark Streaming是构建在Spark上的流计算框架,使得Spark可以同时批处理和流处理。
Spark Streaming输入源可以是kafka,flume,hdfs,tcp socket,输出源可以是关系型数据库,HDFS。经过处理的数据可以存储在文件系统、数据库。
基本原理
将实时输入数据流以时间片的单位进行拆分,然后用spark引擎,以类批处理方式处理每个时间片数据。
拆分成batches of input data.
数据对象
DStream,表示连续不断的数据流。每一段数据都转换为rdd,并且对DStream的操作都转变为对RDD的操作。
DStream操作概述
存在一个组件Receiver,作为一个长期运行的任务Task在Executor上运行,每个Receiver负责一个DStream输入流。
编写Spark Streaming程序基本步骤
- 创建输入DStream定义输入流
- 通过对DSteam转换操作和输出操作来定义流计算
- 调用Streaming Context对象的start()来开始接收数据和处理流程
- 调用Streaming Context对象的awaitTermination()方法等来流计算进程结束,或调用stop()结束流计算进程
创建StreamingContext对象
ssc = StreamingContext(sc,1)
sc是SparkContext对象,1表示每1秒切成一个分段。所以无法实现毫秒级别的流计算。
输入源
文件流
文件流,对文件系统的某个目录进行监听,有新的文件生成,就把文件内容读取过来。
ssc = StreamingContext(sc,1)
lines = ssc.textFileStream('logfile')
word = lines.flatMap(lambda line: line.split(' '))
wordCount = word.map(lambda x: (x,1)).reduceByKey(lambda x,y:x+y)
wordCount.pprint()
ssc.start()
ssc.awaitTermination()
套接字流
可以通过Socket端口监听并接收数据。
ssc.socketTextStream(主机地址,端口号)
RDD队列流
可以调用StreamingContext对象的queueStream()方法来创建基于RDD队列的DStream。
ssc.queueStream(rddQueue)
Kafka源
可以把Kafka或Flume作为数据源。使用KafkaUtils创建输入流。
转换操作
无状态操作,不会记录历史状态信息,每次对新的批次数据进行处理,只会记录当前批次数据的状态。
有状态转换操作则会记录历史状态信息,包括滑动窗口转换操作和updateStateByKey操作。
滑动窗口转换操作
事先设定一个滑动窗口的长度,设定滑动窗口的间隔(每隔多久执行一次计算)。
updateStateByKey操作
滑动窗口操作,只能对当前窗口内的数据进行计算,无法在跨批次之间维护状态。如果要在跨批次之间维护状态,就必须使用updateStateByKey操作。
会在之前批次的结果上的基础上不断累加。updateStateByKey会根据key对当前批次内的所有key,value进行计算,把所有key相同的进行合并。得到(key,value-list)。
输出操作
把DStream的数据输出到文本文件或关系数据库中。
saveAsTextFiles()//写入文本
//写入数据库和RDD写入数据库一样