Discretized Stream是Spark Streaming的基础抽象,代表持续性的数据流和经过各种Spark算子操作后的结果数据流。
在SparkStreaming企业实际开发中,建议:能对RDD操作的就不要对DStream操作,当调用DStream中某个函数在RDD中也存在,使用针对RDD操作。
模拟TCP socket实现简单的实时计算wordcount
import org.apache.spark.streaming.dstream.{
DStream, ReceiverInputDStream}
import org.apache.spark.streaming.{
Seconds, StreamingContext}
import org.apache.spark.{
SparkConf, SparkContext}
/**
* @author liu a fu
* @date 2021/1/20 0020
* @version 1.0
* @DESC 第一个SparkStreaming wordcount案例 不会累加(称之为无状态计算)
*
* 1-首先声明StreamingContext申请资源,进入调用sparkContext
* 2-这里从socket接受数据,从node1节点下安装nc服务,使用nc -lk 9999端口发送数据**
* 3-将接受到的数据进行Tranformation转换
* 4-使用OutPutOpration操作输出结果
* 5-开启start,streamingcontext.start开启接受数据
* 6-指导StreamingContext.awaitTermination停止
* 7-StreamingContext.stop
*/
object _01StreamingCompution {
def main(args: Array[String]): Unit = {
//1-首先声明StreamingContext申请资源,进入调用sparkContext
val conf: SparkConf = new SparkConf()
.setMaster("local[8]")
.setAppName(this.getClass.getSimpleName.stripSuffix("$"))
val sc = new SparkContext(conf)
val ssc = new StreamingContext(sc, Seconds(5)) //每经过5秒处理一次数据
sc.setLogLevel("WARN")
//2-这里从socket接受数据,从node1节点下安装nc服务,使用nc -lk 9999端口发送数据
val receiveDS: ReceiverInputDStream[String] = ssc.socketTextStream("node1", 9999) //指定主机和端口
//3-将接受到的数据进行Tranformation转换
val resultDS: DStream[(String, Int)] = receiveDS
.flatMap(_.split("\\s+"))
.map((_, 1))
.reduceByKey(_ + _)
//4-使用OutPutOpration操作输出结果-----------print属于类似于action算子的
resultDS.print()
//5-开启start,streamingcontext.start开启接受数据
ssc.start() //Start the execution of the streams.
//6-指导StreamingContext.awaitTermination停止,有任何的异常都会触发停止
ssc.awaitTermination()
//7-StreamingContext.stop
ssc.stop()
}
}
模拟TCP 实现排序(transform转换算子 + sortBy实现)
import org.apache.spark.rdd.RDD
import org.apache.spark.streaming.dstream.{
DStream, ReceiverInputDStream}
import org.apache.spark.streaming.{
Seconds, StreamingContext}
import org.apache.spark.{
SparkConf, SparkContext}
/**
* @author liu a fu
* @date 2021/1/20 0020
* @version 1.0
* @DESC 实现wordcount统计后的排序输出
*/
object _02SreamingCompution {
def main(args: Array[String]): Unit = {
//1-首先声明StreamingContext申请资源,进入调用sparkContext
val conf: SparkConf = new SparkConf().setAppName(this.getClass.getSimpleName.stripSuffix("$")).setMaster("local[3]")
val sc = new SparkContext(conf)
val scc = new StreamingContext(sc, Seconds(5))
sc.setLogLevel("WARN")
//2-这里从socket接收数据
val reviceDS: ReceiverInputDStream[String] = scc.socketTextStream("node1", 9999)
//3-将接收的数据进行Tranformation转换
val resultDS: DStream[(String, Int)] = reviceDS
.flatMap(_.split("\\s+"))
.map((_, 1))
.reduceByKey(_ + _)
//实现排序操作
val output: DStream[(String, Int)] = resultDS.transform(iter => {
val valueRDD: RDD[(String, Int)] = iter.sortBy(_._2, false) //按照第二个进行排序 value
valueRDD
})
//4-使用OutPutOpration操作输出结果-----------print属于类似于action算子的
output.print()
//5-开启start,streamingcontext.start开启接受数据
scc.start()
scc.awaitTermination()
scc.stop()
}
}
TCP 实现有状态 累加(updateStateByKey算子 定义方法)
import org.apache.spark.streaming.dstream.{
DStream, ReceiverInputDStream}
import org.apache.spark.streaming.{
Seconds, StreamingContext}
import org.apache.spark.{
SparkConf, SparkContext}
/**
* @author liu a fu
* @date 2021/1/20 0020
* @version 1.0
* @DESC SparkStreaming wordcount案例 会累加(称之为有状态计算)
*/
object _03StreamingComput {
/**
* 这里自己定义的一个方法用于累加 和 判断历史值是否存在
* @param currentValue 这里是当前的值,需要是用sum累加
* @param historyValue 这里是历史的值,判断历史的值是否存在,如果存在直接使用,如果不存在赋值为0
* @return
*/
def updateFunc(currentValue:Seq[Int],historyValue:Option[Int]):Option[Int] = {
val addSum = currentValue.sum + historyValue.getOrElse(0)
Option(addSum)
}
def main(args: Array[String]): Unit = {
val conf: SparkConf = new SparkConf().setAppName(this.getClass.getSimpleName.stripSuffix("$")).setMaster("local[5]")
val sc = new SparkContext(conf)
val scc = new StreamingContext(sc, Seconds(5))
sc.setLogLevel("WARN")
scc.checkpoint("data/checkpoint/check001")
2-这里从socket接受数据,从node1节点下安装nc服务,使用nc -lk 9999端口发送数据
val reviceDS: ReceiverInputDStream[String] = scc.socketTextStream("node1", 9999)
//3-将接受到的数据进行Tranformation转换
val resultDS: DStream[(String, Int)] = reviceDS
.flatMap(_.split("\\s+"))
.map((_, 1))
.updateStateByKey(updateFunc)
//4-使用OutPutOpration操作输出结果-----------print属于类似于action算子的
resultDS.print()
//5-开启start,streamingcontext.start开启接受数据
scc.start() //Start the execution of the streams.
//6-指导StreamingContext.awaitTermination停止,有任何的异常都会触发停止
scc.awaitTermination()
scc.stop()
}
}
运行上述词频统计案例,登录到WEB UI监控页面:http://localhost:4040,查看相关监控信息。