Spark Streaming算子--updateStateByKey,transform
1.updateStateByKey算子
updateStateByKey算子维护一个“状态”,可以将当前流处理的结果和过去流处理的结果进行“合并”。
一个WordCount的简单例子:
object StatefulNetworkWordCount {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local[2]").setAppName("StatefulNetworkWordCount")
val ssc = new StreamingContext(conf,Seconds(5))
ssc.checkpoint(".")
val lines = ssc.socketTextStream("localhost",6789)
val result = lines.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_)
val state = result.updateStateByKey(updateFunction);
state.print()
ssc.start()
ssc.awaitTermination()
}
//通过状态更新函数将过去wordcount的结果和当前结果合并,实现全局的WordCount
def updateFunction(currentValues:Seq[Int], preValues:Option[Int]) = {
val current = currentValues.sum
val pre = preValues.getOrElse(0)
Some(current + pre)
}
}
2.transform算子
transform算子可以用来对DStream和其他的DataSet(rdd)进行运算。
比如:将DStream每个批次中的RDD和另一个Dataset进行关联(join)操作,这个功能DStream API并没有直接支持,可以用transform实现。
比如:用事先确定好的黑名单rdd,对DStream进行实时过滤。
下面是一个简单的黑名单过滤的例子:
object TransformApp {
def main(args: Array[String]): Unit = {
val sparkconf = new SparkConf().setMaster("local[2]").setAppName("NetWordCount")
val ssc = new StreamingContext(sparkconf,Seconds(5))
val lines = ssc.socketTextStream("localhost",6789)
/**
* 黑名单 "zs","ls"
* 转化为rdd: ("zs",true) (“ls”,true)
**/
val blacks = List("zs","ls")
val blacksRDD = ssc.sparkContext.parallelize(blacks).map(x=>(x,"true"))
/**
* 输入数据:20170808,zs
* 20170809,ls
* 20170810,ww
* 左连接后:
* (zs:<20170808,zs>,<true>)
* (ls:<20170809,ls>,<true>)
* (ww:<20170810,ww>,<false>)
* =>过滤后剩下: 20170810,ww
**/
val res = lines.map(x=>(x.split(",")(1),x)).transform(rdd => {
// 将DStream中的RDD和blacksRDD关联,并实时过滤垃圾数据
rdd.leftOuterJoin(blacksRDD)
.filter(x=>x._2._2.getOrElse("false")!="true")
.map(x=>x._2._1)
})
res.print()
ssc.start()
ssc.awaitTermination()
}
}

浙公网安备 33010602011771号