首先是窗口操作普通机制
package com.fengrui.test
import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
import org.apache.spark.streaming.{Durations, StreamingContext}
import org.apache.spark.{SparkConf, SparkContext, streaming}
/**
* SparkStreaming 窗口操作
* reduceByKeyAndWindow只是一种特殊的实现,根据reduceByKey逻辑操作
* 每隔窗口滑动间隔时间 计算窗口长度内的数据,按照指定方式处理
* 比如说我每隔5秒钟想看过去15秒一共有多少个hello单词,这时候updateStateByKey就满足不了业务需求了
*/
object WindowOperator {
def main(args: Array[String]): Unit = {
val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("WindowOperator")
val sc = new SparkContext(conf)
val ssc = new StreamingContext(sc,Durations.seconds(5))
val lines: ReceiverInputDStream[String] = ssc.socketTextStream("hdp-1",9999)
val words: DStream[String] = lines.flatMap(_.split(" "))
val word: DStream[(String, Int)] = words.map((_,1))
/**
* 窗口操作普通机制
* 第一个参数是监测的数据,第二个参数是窗口长度,第三个是滑动间隔
* 代表每五秒查看前十五秒数据
* 这里的时间必须是 batchinterval 整数倍
*/
val res: DStream[(String, Int)] =
word.reduceByKeyAndWindow((v1:Int,v2:Int) => {v1 + v2},Durations.seconds(15),Durations.seconds(5))
res.print()
ssc.start()
ssc.awaitTermination()
}
}
优化窗口操作
package com.fengrui.test
import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
import org.apache.spark.streaming.{Durations, StreamingContext}
import org.apache.spark.{SparkConf, SparkContext, streaming}
/**
* SparkStreaming 窗口操作
* reduceByKeyAndWindow只是一种特殊的实现,根据reduceByKey逻辑操作
* 每隔窗口滑动间隔时间 计算窗口长度内的数据,按照指定方式处理
* 比如说我每隔5秒钟想看过去15秒一共有多少个hello单词,这时候updateStateByKey就满足不了业务需求了
*/
object WindowOperator {
def main(args: Array[String]): Unit = {
val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("WindowOperator")
val sc = new SparkContext(conf)
val ssc = new StreamingContext(sc,Durations.seconds(5))
val lines: ReceiverInputDStream[String] = ssc.socketTextStream("hdp-1",9999)
val words: DStream[String] = lines.flatMap(_.split(" "))
val word: DStream[(String, Int)] = words.map((_,1))
/**
* 窗口操作优化的机制
* 比如说我们还是每隔五秒查看一下前十五秒数据,我们可以加上新进来的批次,再减去出去的批次,防止任务堆积
* 用优化机制必须设置checkpoint,不设置会报错
* 第一个参数是先加上新来的批次
* 第二个参数是减去出去的批次
* 第三个参数是窗口长度
* 第四个参数是滑动间隔
*/
ssc.checkpoint("/test")
val res: DStream[(String, Int)] = word.reduceByKeyAndWindow(
(v1: Int, v2: Int) => {v1 + v2},
(v1: Int, v2: Int) => {v1 - v2},
Durations.seconds(15),
Durations.seconds(15)
)
res.print()
ssc.start()
ssc.awaitTermination()
}
}
也可以根据自己需求调用window
package com.fengrui.test
import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
import org.apache.spark.streaming.{Durations, StreamingContext}
import org.apache.spark.{SparkConf, SparkContext, streaming}
/**
* SparkStreaming 窗口操作
* reduceByKeyAndWindow只是一种特殊的实现,根据reduceByKey逻辑操作
* 每隔窗口滑动间隔时间 计算窗口长度内的数据,按照指定方式处理
* 比如说我每隔5秒钟想看过去15秒一共有多少个hello单词,这时候updateStateByKey就满足不了业务需求了
*/
object WindowOperator {
def main(args: Array[String]): Unit = {
val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("WindowOperator")
val sc = new SparkContext(conf)
val ssc = new StreamingContext(sc,Durations.seconds(5))
val lines: ReceiverInputDStream[String] = ssc.socketTextStream("hdp-1",9999)
val words: DStream[String] = lines.flatMap(_.split(" "))
val word: DStream[(String, Int)] = words.map((_,1))
/**
* 我们如果有自己的操作逻辑
* 我们也可以使用Window
*/
val win: DStream[(String, Int)] = word.window(Durations.seconds(15),Durations.seconds(5))
val res: DStream[(String, Int)] = win.reduceByKey(_+_)
res.print()
ssc.start()
ssc.awaitTermination()
}
}