spark streaming转换操作
1.无状态转换
map操作:源 为DStream,一次一对一转换。
flatMap:一个输入映射成0或多个输出项。
filter:过滤,满足条件的过滤出来。
repartition:改变DStream用的分区数。
reduce:提供聚合函数,进行聚合运算。
count:统计源DStream中每个RDD的元素数量。
union:合并多个DStream。
countByValue:统计元素出现次数。
reduceByKey:根据key进行聚合运算。
join:把两个key相同的给join起来。
以上都是无状态转换,当前批次进行转换,下一批次时上一批次丢掉,与上一批次无关,对新的批次进行计算。
2.有状态转换
希望词频统计基于以前结果累加。滑动窗口转换操作和updateStateByKey操作。
滑动窗口:参数给出滑动窗口大小,滑动时间间隔大小。
countByWidow:返回流中元素的一个滑动窗口数。
reduceByWindow:返回一个单元素流,当前窗口内元素使用func聚合得到一个值,每个窗口一个值。
reduceByKeyAndWindow:对窗口实现reduceByKey计算,func,逆函数(逆向操作提高整个程序运算效率,窗口移动部分被淘汰,部分新进,逆函数不需要全部重新统计,只需要减掉旧的,添加新的即可,实现了增量计算。如图),窗口长,滑动间隔,设定启动几个线程并行处理。
updateStateByKey:跨批次之间维护状态,累加上一批次词频。
updateStateByKey实现基于套接字的词频统计:
object NetworkWordCountStateful {
def main(args: Array[String]) {
//定义状态更新函数
val updateFunc = (values: Seq[Int], state: Option[Int]) => {
val currentCount = values.foldLeft(0)(_ + _)//当前所有相同的归并自动的,values为当前词频values,state为当前历史词频,0+1+1
val previousCount = state.getOrElse(0)//如果未出现过则为none,此处设为0
Some(currentCount + previousCount)//两者累加封装到some返回,对hadoop统计完再对spark词统计
}
StreamingExamples.setStreamingLogLevels() //设置log4j日志级别
val conf = new SparkConf().setMaster("local[2]").setAppName("NetworkWordCountStateful")
val sc = new StreamingContext(conf, Seconds(5))
sc.checkpoint("home/ziyu_bigdata/quick_learn_spark/checkpoint") //设置检查点,检查点具有容错机制
val lines = sc.socketTextStream("localhost", 9999)
val words = lines.flatMap(_.split(" "))
val wordDstream = words.map(x => (x, 1))
// 跨批次状态维护,当前所有相同的归并,
val stateDstream = wordDstream.updateStateByKey[Int](updateFunc)
// 结果打印
stateDstream.print()
sc.start()
sc.awaitTermination()
}
}