一:使用场景

1.应用场景

  数据的累加

  一段时间内的数据的累加

2.说明

  每个批次都输出自己批次的数据,

  这个时候,可以使用这个API,使得他们之间产生联系。

3.说明2

  在累加器的时候,起到的效果和这里的说明想法有些相同,都可以输出上一个批次的信息

二:程序

1.需要启动一些服务

  需要使用hadoop

  

2.程序

 package com.stream.it

 import kafka.serializer.StringDecoder
import org.apache.spark.rdd.RDD
import org.apache.spark.storage.StorageLevel
import org.apache.spark.streaming.kafka.KafkaUtils
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.{HashPartitioner, SparkConf, SparkContext} object UpdateStateByKeyKafkaWordcount {
def main(args: Array[String]): Unit = {
val conf=new SparkConf()
.setAppName("spark-streaming-wordcount")
.setMaster("local[*]")
val sc=SparkContext.getOrCreate(conf)
val ssc=new StreamingContext(sc,Seconds(15)) val kafkaParams=Map("group.id"->"stream-sparking-0",
"zookeeper.connect"->"linux-hadoop01.ibeifeng.com:2181/kafka",
"auto.offset.reset"->"smallest"
)
val topics=Map("beifeng"->1)
val dStream=KafkaUtils.createStream[String,String,StringDecoder,StringDecoder](
ssc, //给定sparkStreaming的上下文
kafkaParams, //kafka的参数信息,通过kafka HightLevelComsumerApi连接
topics, //给定读取对应的topic的名称以及读取数据的线程数量
StorageLevel.MEMORY_AND_DISK_2 //数据接收器接收到kafka的数据后的保存级别
).map(_._2) // 当调用updateStateByKey函数API的时候,必须给定checkpoint dir
// 路径对应的文件夹不能存在
ssc.checkpoint("hdfs://linux-hadoop01.ibeifeng.com:8020/beifeng/spark/streaming/chkdir01") /**
def updateStateByKey[S: ClassTag](
updateFunc: (Seq[V], Option[S]) => Option[S],
partitioner: Partitioner,
initialRDD: RDD[(K, S)]
): DStream[(K, S)]
*/ val resultWordcount=dStream
.filter(line=>line.nonEmpty)
.flatMap(line=>line.split(" ").map((_,1)))
.reduceByKey(_+_)
.updateStateByKey(
(values: Seq[Int], state: Option[Long]) => {
// 从value中获取累加值
val sum = values.sum // 获取以前的累加值
val oldStateSum = state.getOrElse(0L) // 更新状态值并返回
Some(oldStateSum + sum)
}
) resultWordcount.foreachRDD(rdd=>{
rdd.foreachPartition(iter=>iter.foreach(println))
}) //启动
ssc.start()
//等到
ssc.awaitTermination()
}
}

三:updateStateByKey的优化

1.说明

  主要的情况是,程序停止,刚刚累加的数据不再存在。

  重启后效果如下:

    只剩下,已经被checkPoint的数据,后面的数据不再存在。

    

2.优化的程序

  多加两个参数。

 package com.stream.it

 import kafka.serializer.StringDecoder
import org.apache.spark.rdd.RDD
import org.apache.spark.storage.StorageLevel
import org.apache.spark.streaming.kafka.KafkaUtils
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.{HashPartitioner, SparkConf, SparkContext} object UpdateStateByKeyKafkaWordcount {
def main(args: Array[String]): Unit = {
val conf=new SparkConf()
.setAppName("spark-streaming-wordcount")
.setMaster("local[*]")
val sc=SparkContext.getOrCreate(conf)
val ssc=new StreamingContext(sc,Seconds(15)) val kafkaParams=Map("group.id"->"stream-sparking-0",
"zookeeper.connect"->"linux-hadoop01.ibeifeng.com:2181/kafka",
"auto.offset.reset"->"largest"
)
val topics=Map("beifeng"->1)
val dStream=KafkaUtils.createStream[String,String,StringDecoder,StringDecoder](
ssc, //给定sparkStreaming的上下文
kafkaParams, //kafka的参数信息,通过kafka HightLevelComsumerApi连接
topics, //给定读取对应的topic的名称以及读取数据的线程数量
StorageLevel.MEMORY_AND_DISK_2 //数据接收器接收到kafka的数据后的保存级别
).map(_._2) // 当调用updateStateByKey函数API的时候,必须给定checkpoint dir
// 路径对应的文件夹不能存在
ssc.checkpoint("hdfs://linux-hadoop01.ibeifeng.com:8020/beifeng/spark/streaming/chkdir01") // 初始化updateStateByKey用到的状态值
// 从保存状态值的地方(HBase)读取状态值, 这里采用模拟的方式
val initialRDD: RDD[(String, Long)] = sc.parallelize(
Array(
("hadoop", 100L),
("spark", 25L)
)
) /**
def updateStateByKey[S: ClassTag](
updateFunc: (Seq[V], Option[S]) => Option[S],
partitioner: Partitioner,
initialRDD: RDD[(K, S)]
): DStream[(K, S)]
*/ val resultWordcount=dStream
.filter(line=>line.nonEmpty)
.flatMap(line=>line.split(" ").map((_,1)))
.reduceByKey(_+_)
.updateStateByKey(
(values: Seq[Int], state: Option[Long]) => {
// 从value中获取累加值
val sum = values.sum // 获取以前的累加值
val oldStateSum = state.getOrElse(0L) // 更新状态值并返回
Some(oldStateSum + sum)
},
new HashPartitioner(ssc.sparkContext.defaultParallelism), // 分区器
initialRDD // 初始化状态值
) resultWordcount.foreachRDD(rdd=>{
rdd.foreachPartition(iter=>iter.foreach(println))
}) //启动
ssc.start()
//等到
ssc.awaitTermination()
}
}

3.运行效果

  

4.注意点

  需要有checkPoint的路径。

  累加值存在硬盘中,长时间不访问会被删除。

065 updateStateByKey的函数API的更多相关文章

  1. HTML5 Audio标签方法和函数API介绍

    问说网 > 文章教程 > 网页制作 > HTML5 Audio标签方法和函数API介绍 Audio APIHTML5HTML5 Audio预加载 HTML5 Audio标签方法和函数 ...

  2. MySQL Crash Course #05# Chapter 9. 10. 11. 12 正则.函数. API

    索引 正则表达式:MySQL only supports a small subset of what is supported in most regular expression implemen ...

  3. Unix/Linux系统时间函数API

    首先说明关于几个时间的概念: 世界时:起初,国际上的标准时间是格林尼治标准时间,以太阳横穿本初子午线的时刻为标准时间正午12点.它根据天文环境来定义,就像古代人们根据日晷来计时一样,如下图: 原子时: ...

  4. Atitit.跨平台预定义函数 魔术方法 魔术函数 钩子函数 api兼容性草案 v2 q216  java c# php js.docx

    Atitit.跨平台预定义函数 魔术方法 魔术函数 钩子函数 api兼容性草案 v2 q216  java c# php js.docx 1.1. 预定义函数 魔术方法 魔术函数是什么1 1.2. & ...

  5. kotlin函数api

    原 Kotlin学习(4)Lambda 2017年09月26日 21:00:03 gwt0425 阅读数:551   记住Lambda的本质,还是一个对象.和JS,Python等不同的是,Kotlin ...

  6. jQuery函数API,各版本新特性汇总

    jQuery API 速查表 选择器 基本 #id element .class * selector1,selector2,selectorN 层级 ancestor descendant pare ...

  7. Azure 静态 web 应用集成 Azure 函数 API

    前几次我们演示了如果通过Azure静态web应用功能发布vue跟blazor的项目.但是一个真正的web应用,总是免不了需要后台api服务为前端提供数据或者处理数据的能力.同样前面我们也介绍了Azur ...

  8. cocosCreator 新版本的动作函数API的应用

    利用触摸位置判断,点击的是屏幕的左侧还是右侧,控制主角左右移动: 见代码: InputControl:function () { var self=this; //cc.systemEvent sel ...

  9. 【原创】自己动手写的一个查看函数API地址的小工具

    C开源代码如下: #include <stdio.h> #include <windows.h> #include <winbase.h> typedef void ...

随机推荐

  1. 洛谷P3246 [HNOI2016]序列 [莫队]

    传送门 思路 看到可离线.无修改.区间询问,相信一定可以想到莫队. 然而,莫队怎么转移是个大问题. 考虑\([l,r]\rightarrow[l,r+1]\)时答案会怎样变化?(左端点变化时同理) \ ...

  2. python 启动虚拟环境

    假设你有两个Python项目-A和B,这两个项目都需要使用同一个第三方模块-tensorflow.如果这两个项目使用相同的tensorflow版本,也许不会有什么问题. 但是,当A和B项目使用不同的t ...

  3. SVG前戏—让你的View多姿多彩

    什么是SVG SVG的全称是Scalable Vector Graphics,叫可缩放矢量图形.是一种基于可扩展标记语言(XML).它和位图(Bitmap)相对,SVG不会像位图一样因为缩放而让图片质 ...

  4. Oracle 所有的权限列表

  5. FTP服务器配置和管理

    一:ftp 简介 1:ftp服务: internet 是一个非常复杂额计算机环境,其中有pc/mac/小型机/大型机等.而在这些计算机上运行的操作系统也是五花八门,有 unix.Linux.微软的wi ...

  6. Confluence 6 从一个备份中获得文件附件

    页面中的文件附件可以从备份中获得而不需要将备份文件导入到 Confluence 中.这个在用户删掉了附件,但是你还是想恢复这个附件的时候就变得非常有用了. 自动备份和手动备份都允许你进行这个操作,但是 ...

  7. 理解call及apply

    转载自:http://www.zhihu.com/question/20289071 //call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改 ...

  8. mysql之视图,触发器,事务等。。。

    一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...

  9. 【kafka】设置指定topic和group_id消耗的offset

    该博文方法有问题,正确方案在http://www.cnblogs.com/dplearning/p/7992994.html 背景: 搭建了一个kafka集群,建立了topic test,用group ...

  10. python基础之迭代器与生成器

    一.什么是迭代器: 迭代是Python最强大的功能之一,是访问集合元素的一种方式. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束. 迭代器是一个可以记住遍历的位置的对象. 迭代器的 ...