UpdateStateByKey操作(按照key更新状态)
其它案例都是之前spark用到过的,以下是特殊RDD
(之前案例统计的是5秒内的总次数,并不是wordcount的总次数,此Rdd可以统计整个流 流过的内容的wordcount总次数)
该updateStateByKey操作允许您在使用新信息不断更新时保持任意状态。要使用它,您必须执行两个步骤。
- 定义状态 - 状态可以是任意数据类型。
- 定义状态更新功能 - 使用函数指定如何使用先前状态和输入流中的新值更新状态。
在每个批处理中,Spark都会对所有现有Key状态更新功能,无论它们是否在批处理中,都有新数据。
如果更新函数返回None,则将删除键值对。
请注意,使用updateStateByKey需要配置检查点目录
让我们举一个例子来说明这一点。
假设您要维护文本数据流中看到的每个单词的运行计数(单词统计, 根据key操作)
import org.apache.spark.SparkConf
import org.apache.spark.streaming.{Seconds, StreamingContext}
object updateStateByKeyStreaming {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local[2]").setAppName("NetworkWordCount")
//批次,时间切片
val ssc = new StreamingContext(conf, Seconds(5))
//1.增加检查点,会在E盘生成aaa文件夹 每次计算结果保存,也就是需要做updateStateByKey就必须有检查点将流上次内容保存到检查点中
ssc.checkpoint("E://aaa") //ssc.checkpoint("hdfs://master:9000/aaa") 如报权限问题,修改hdfs创建文件的权限
//使用自定义的接收器
val lines = ssc.receiverStream(new CustomReceiver("master", 9999))
val words = lines.flatMap(_.split(" "))
val pairs = words.map(word => (word, 1))
val wordCount = pairs.reduceByKey(_ + _)
//3.用wordCount调用updateStateByKey函数
val wordCounts = wordCount.updateStateByKey(updateFunction)
wordCounts.print()
ssc.start() // 开始计算
ssc.awaitTermination() // 等待计算结束
}
//2.当前计数器结果
//上一个计数器结果,第一次进来没有值 Option【None 、Some】
def updateFunction(newValues: Seq[Int], runningCount: Option[Int]): Option[Int] = {
val newCount = runningCount.getOrElse(0) // 使用前一个正在运行的计数添加新值,以获得新计数
Some(newCount+newValues.sum) //相加
/*val newCounts = runningCount.getOrElse(0) + newValues.foldLeft(0)(_+_)
Some(newCounts)*/
}
}
spark-submit提交
[hyxy@master Desktop]$ spark-submit --help
Options:
--class CLASS_NAME Your application's main class (for Java / Scala apps).
--master spark:7077 独立
--master local[*] 本地
--master client spark on yarn
案例1,通过nc发送消息, spark-submit运行SparkStreaming程序
1)编写sparkStreaming程序 package 打包
【package com.hyxy.sparkStreaming】
import org.apache.spark._
import org.apache.spark.streaming._
object NcSparkStreaming{
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local[2]").setAppName("NetworkWordCount")
val ssc = new StreamingContext(conf, Seconds(5))
val lines = ssc.socketTextStream("master", 9999)
val words = lines.flatMap(_.split(" "))
val pairs = words.map(word => (word, 1))
val wordCounts = pairs.reduceByKey(_ + _)
// Print the first ten elements of each RDD generated in this DStream to the console
wordCounts.print()
ssc.start() // Start the computation
ssc.awaitTermination()
}
}
2) 打包 package右键Run 项目名(第二项)
生成目录target下
将spark01-1.0-SNAPSHOT.jar拷贝到Liunx下
3)开启nc -l 9999
4)spark-submit提交
spark-submit --class com.hyxy.NcSp