spark streaming checkpointing windows
spark streaming的相关概念:
spark的核心是创建一个RDD对象,然后对RDD对象进行计算操作等
streaming可以理解为是 一个连续不断的数据流 ,然后将每个固定时间段里的数据构建成一个RDD,然后就会创一连串的RDD流,这就是DStream(streaming的主要操作对象)
batch 就是上面所说的固定时间段的时间表示,可以为5秒,10秒or ect ,DStream中每个RDD接收数据的时间,也作 mini-batch
window 用于装载上述【一个bactch内数据所创建的RDD】 的容器,容器的大小用时间表示(毫秒,秒,分钟等),必须为 batch的倍数,window 内的RDD也会随时间而不断更新,window的更新间隔称为duration ,必须为batch的倍数。
如下图 可理解为一个RDD的batch为5秒 ,一个window的容积是2个RDD的batch即10秒,window的duration为一个batch 5秒。
即window每次滑动的距离为5秒,1个RDD。

使用checkpointing更新数据的代码示例
统计文件中的数据,并使用updateStateByKey来更新结果
Scala版
package wordcounttest import org.apache.spark._
import org.apache.spark.streaming._
import java.sql.Timestamp
import org.apache.spark.streaming.dstream.DStream Object SteamingTest{
def main(args:Array[String]){
val conf = new SparkConf().setMaster("local[4]").setAppName("test1")
val sc = new SparkContext(conf)
// 这里设置 Dstream 的batch 是 5 秒
val ssc = new StreamingContext(sc,Seconds(5))
val filestream = ssc.textFileStream("/home/spark/cho6input") //设置dstream 数据来源,在ssc.start()后这个目录中新生成的txt文件都会被读入 //定义一个处理order的class
case class Order(time:java.sql.TimeStamp, OrderId:Long, clientId:Long,symbol:String,amount:Int,price:Double,buy:Boolean) val orders = filestream.flatMap(line => {
val dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss") //设置要解析的时间数据的字符型式
val s = line.split(",")
try{
assert(s(6) == "B" || s(6) == "S")
List(Order(new Timestamp(dateFormat.parse(s(0)).getTime()),s(1).toLong,s(2).toLong,s(3),s(4).toInt,s(5).toDouble,s(6) == "B"))
}
catch{
case e: Throwable => println("Wrong line format(" + e + "):" +line)
List()
}
})
val numPerType = orders.map(o => (o.buy,1L)).reduceByKey((c1,c2) => c1+c2) val amountPerClient = orders.map(o => (o.clientId,o.amount*o.price))
val amountState = amountPerClient.updateStateByKey((vals,totalOpt:Option[Double]) => {
totalOpt match{
case Some(total) => Some(total +vals.sum)
case None => Some(vals.sum)
}
}
val updateAmountState = (clinetId:Long,amount:Option[Double],state:State[Double]) => {
var total = amount.getOrElse(0.toDouble)
if(state.exists())
total += state.get()
state.update(total)
Some((clientId,total))
}
// map
val amountState2 = amountPerClient.mapWithState(StateSpec.function(updateAmountState)).stateSnapshots() val top5clients = amountState.transform( _.sortBy(_._2,false).map(_._1).zipWithIndex.filter(x =>x._2 <5))
val buySellList = numPerType.map( t => if(t._1) ("BUYS",List(t._2.toString)) else ("SELLS",List(t._2.toString)) )
val top5clList = top5clients.repartition(1).map(x => x._1.toString).glom().map(arr => ("TOP5CLIENTS",arr.toList))
val finaleStream = buySellList.union(top5clList) finalStream.repartition(1).saveAsTextFiles("/home/spark/ch06output/output","txt")
sc.setCheckpointDir("/home/spark/checkpoint")
ssc.start() }
updateStateByKey(func)使用说明
updateStateByKey一般只需要一个参数 -- func(vals,optdata) 这个func的入参是(一个数据队列vals 和一个Option类型的数据) 返回值是Option类型数据
vals是当前新的batch中接收的数据队列 ,Option类型的数据是 上个batch的计算的保存的结果 , 返回值option类型的数据是当前计算的结果
通过设置 checkpoint 使用updateStateByKey计算所得的结果会自动保存,下个batch计算时会自动读取
mapWithState(func)使用说明
mapWithState(func)的入参 也只需一个func ,这个func通过org.apache.spark.streaming.StateSpec.function()包裹
的一个方法,这个方法的形式为(key,value,optionstate,maptypestate) 即入参为 key,value,上次保存的option类型的状态值,
返回值为option类型的另一种类型的状态值。即上次保存的状态值类型和 当前生成的状态值类型可以不同。
区别: updateStateByKey的func的入参 上次保存的状态值 和 生成的状态值类型 需要相同
mapWithState的func的入参 上次保存的状态值 和 生成的状态值类型 可以不同
checkpointing说明
如果通过 sc.setCheckpointDir('some/path')设置了checkpoint的目录
streaming就会自动在某些时刻 对当前的 DStreaming的信息保存,以便下一次需要历史数据时不用重新计算,可以直接获取;
也可用于故障恢复,streaming重启时根据之前保存 的RDD信息来创建RDD。
使用 checkpoint时一般只需设置CheckpointDir保存当前状态信息的目录,也可设置checkpoint的各个保存点的时间间隔,即每隔多长时间保存一次当前RDD的信息。
chekPoint 是spark streaming 内部自动机制,根据流程图中是否有使用到【需要状态保存点的转换函数】来自动保存某个点的状态信息及计算结果
checkpointing saves an RDD's data and its complete DAG(an RDD's calculation plan),当一个executor异常,RDD不需要从头开始计算,可以从硬盘
中读取存储的结果
【需要考虑过去的计算状态的方法】spark主要提供了两个updateStateByKey 和mapWithState 这两个方法的使用者必须是PairDStream对象,
即(key,value)形式的DStream。 使用updateStateByKey时,state会随每一个新batch变化而变化
http://spark.apache.org/docs/2.3.3/streaming-programming-guide.html#checkpointing
如果需要应用从异常中进行故障恢复 , 就需要改进 streaming 应用,使其 实现了如下逻辑
- 当应用是第一个被开启, 则它会创建一个新的 StreamingContext ,来启动所有的streams 然后call start()
- 当应用是在故障后被重启 ,则它会根据 checkpoint目录中的checkpoint 数据来重新创建一个StreamingContext
实现逻辑 ,使用StreamingContext.getOrCreate
Python
def functionToCreateContext():
sc = SparkContext(...)
ssc = StreamingContext(...)
lines = ssc.socketTextStream(...)
...
ssc.checkpoint(checkpointDirectory) #设置 checkpoint 目录
return ssc
context = StreamingContext.getOrCreate(checkpointDirectory,functionToCreateContext)
#context的其他的操作
context. ...
context.start()
context.awaitTermination()
如果 checkpointDirectory 存在 ,context就会被根据checkpoint data重新创建
如果不存在(比如说第一次运行),方法 functionToCreateContext就会创建一个新的context 然后启动DStreams
python wordCount故障恢复示例
https://github.com/apache/spark/blob/master/examples/src/main/python/streaming/recoverable_network_wordcount.py
另外 要使用getOrCreate的特性,还需要让driver进程在失败时能自动重启。这只能通过运行这个application 的部署基础设施来实现
RDD的checkpointing会导致性能消耗用于 保存到稳定的存储系统 。 会导致执行了 checkpoint的那些batches处理时间变成 。
因此 checkpointing的时间间隔需要仔细设置 ,对于短时间间隔的batch(比如1秒),在每个batch都进行checkpointing会严重减少处理的数据量
checkpoint太频繁会导致流程线延长和task size增长 。
对于需要rdd checkpointing 的状态性的transformations ,默认的check 间隔是batch间隔的倍数,至少为10秒。
可以通过 dstream.checkpoint(checkpointInterval)进行设置 ,将checkpoint间隔设置为sliding间隔的5-10倍是比较好的做法
Accumulators 累加器 ,Broadcast Variables 广播变量 , checkpoints 检查点
Accumulators ,Broadcast variables 并不能从spark streaming的checkpoint中恢复,所以如果你开启了checkpointing 并且使用了Accumulators或Broadcast variables ,
就需要创建一个 惰性的可实例化单个实例的方法,是它们可以在driver重启时,重新实例化
def getWordBlacklist(sparkContext):
if ("wordBlacklist" not in globals()):
globals()["wordBlacklist"] = sparkContext.broadcast(["a", "b", "c"])
return globals()["wordBlacklist"] def getDroppedWordsCounter(sparkContext):
if ("droppedWordsCounter" not in globals()):
globals()["droppedWordsCounter"] = sparkContext.accumulator(0)
return globals()["droppedWordsCounter"] def echo(time, rdd):
# Get or register the blacklist Broadcast
blacklist = getWordBlacklist(rdd.context)
# Get or register the droppedWordsCounter Accumulator
droppedWordsCounter = getDroppedWordsCounter(rdd.context) # Use blacklist to drop words and use droppedWordsCounter to count them
def filterFunc(wordCount):
if wordCount[0] in blacklist.value:
droppedWordsCounter.add(wordCount[1])
False
else:
True counts = "Counts at time %s %s" % (time, rdd.filter(filterFunc).collect()) wordCounts.foreachRDD(echo)window窗口函数(scala版)
window的操作作用于一系列的mini-batches 上进行滑动,
每个window DStream 决定因素 = ‘window的容量duration持续时间’+ ‘window的滑动间隔(即一个窗口的数据计算的频度)’
这连个参数都是mini-batches的倍数
要统计每个窗口中每种交易量的前5名可以使用window方法,如果wnidow的mini-batch为5分钟,则表示 每5分钟统计一次近60分钟内交易量最大的前5名
先计算近1小时内每个类型的总交易量
val stocksPerWindow = orders.map(x => (x.symbol, x.amount)).window(Minutes(60)).reduceByKey((a1:Int,a2:Int) => a1+a2)
再取前5名
val topStocks = stocksPerWindow.transform(_.sortBy(_._2,false).map(_._1).zipWithIndex.filter(x => x._2 < 5)).repartition(1).
map(x=>x._1.toString).glom().map(arr=>("TOP5STOCKS",arr.toList))
val finalStream = buySellList.union(top5clList).union(topStocks)
finalStream.repartition(1).saveAsTextFiles("/home/spark/ch06output/output","txt")
sc.setCheckpointDir("/home/spark/checkpoint/")
ssc.start()
window相关函数不需要设置checkpoint ,一般的DStream都可以使用,有些需要(k,v)类型的pair DStream才能使用
相关函数如下
window(winDur,[slideDur])
|
函数 |
说明 |
| window(winDur,[slideDur]) | 每隔slideDur时间段,就对windowDur中的RDD计算一次, winDur- 窗口的大小;slideDur窗口滑动的间隔,默认为mini-batch(一个DStream的时间间隔) |
| countByWindow(winDur,slideDur) | 统计当前windowDur中所有RDD包含的元素个数 ,winDur- 窗口的大小;slideDur窗口滑动的间隔 |
| countByValueAndWindow(winDur,slideDur,[numParts]) | 统计当前窗口中distinct元素(无重复元素)的个数,numParts用于修改当前DStream的默认分区数 |
| reduceByWindow(reduceFunc,winDur,slideDur) | 对window中所有RDD的元素应用 reduceFunc方法 |
| reduceByWindow(reduceFunc,invReduceFunc,winDur,slideDur) | 更高效的reduceByWindow方法,对每个window中所有RDD的元素应用reduceFunc方法;去除不属于当前window的rdd元素,使用方法invReduceFunc |
| groupByKeyAndWindow(winDur,[slideDur],[numParts/partitioner]) | 根据key 对window中所有元素进行分组,slideDur可选参数,numParts设置 |
spark streaming checkpointing windows的更多相关文章
- Spark Streaming源码分析 – DStream
A Discretized Stream (DStream), the basic abstraction in Spark Streaming, is a continuous sequence o ...
- Spark Streaming Programming Guide
参考,http://spark.incubator.apache.org/docs/latest/streaming-programming-guide.html Overview SparkStre ...
- Spark Streaming的简单介绍
本文讲解Spark流数据处理之Spark Streaming.本文的写作时值Spark 1.6.2发布之际,Spark 2.0预览版也已发布,Spark发展如此迅速,请随时关注Spark Stream ...
- spark streaming kafka example
// scalastyle:off println package org.apache.spark.examples.streaming import kafka.serializer.String ...
- Spark入门实战系列--7.Spark Streaming(下)--实时流计算Spark Streaming实战
[注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .实例演示 1.1 流数据模拟器 1.1.1 流数据说明 在实例演示中模拟实际情况,需要源源 ...
- Spark Streaming官方文档学习--下
Accumulators and Broadcast Variables 这些不能从checkpoint重新恢复 如果想启动检查点的时候使用这两个变量,就需要创建这写变量的懒惰的singleton实例 ...
- Spark Streaming官方文档学习--上
官方文档地址:http://spark.apache.org/docs/latest/streaming-programming-guide.html Spark Streaming是spark ap ...
- Spark Streaming metadata checkpoint
Checkpointing 一个流应用程序必须全天候运行,所有必须能够解决应用程序逻辑无关的故障(如系统错误,JVM崩溃等).为了使这成为可能,Spark Streaming需要checkpoint足 ...
- Spark Streaming与kafka整合实践之WordCount
本次实践使用kafka console作为消息的生产者,Spark Streaming作为消息的消费者,具体实践代码如下 首先启动kafka server .\bin\windows\kafka-se ...
随机推荐
- 用函数模拟简单的购物车(Python)
""" 购物车功能: a.引导用户输入金额 b.给用户展示所有的商品 c.引导用户输入需要进行的操作[添加 删除 结算购物车 退出] d.引导用户选择商品 e.引导用户输 ...
- PyCharm多行同时输入
按住ALT,用鼠标在需要的位置点击添加光标,然后输入内容即可
- [PHP] stream_set_blocking非阻塞模式影响fgets fread函数
当设置socket为非阻塞时,fread或者fgets函数会立即返回结果,而不需要等待有输入,测试过程可以使用vscode的debug模式来进行当不设置这一项时,如果客户端没有输入会一直阻塞在这里等待 ...
- Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) C. Messy 构造
C. Messy You are fed up with your messy room, so you decided to clean it up. Your room is a bracket ...
- Educational Codeforces Round 76 (Rated for Div. 2) A. Two Rival Students 水题
A. Two Rival Students There are
- 《转》sql处理百万级以上的数据提高查询速度的方法
处理百万级以上的数据提高查询速度的方法: 1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描. 2.对查询进行优化,应尽量避免全表扫描,首先应考 ...
- spring cloud 2.x版本 Gateway动态路由教程
摘要 本文采用的Spring cloud为2.1.8RELEASE,version=Greenwich.SR3 本文基于前面的几篇Spring cloud Gateway文章的实现. 参考 Gatew ...
- 08-Django模板(2)
一.HTML转义 在视图中,通过调用模板传递下文,模板对上下文的传递字符串进行输出时,会对以下字符自动转义.HTML转义的作用:转义后标记代码不会被直接解释执行,而是被直接呈现,防止客户端通过嵌入js ...
- Python爬虫实践~BeautifulSoup+urllib+Flask实现静态网页的爬取
爬取的网站类型: 论坛类网站类型 涉及主要的第三方模块: BeautifulSoup:解析.遍历页面 urllib:处理URL请求 Flask:简易的WEB框架 介绍: 本次主要使用urllib获取网 ...
- java 接口中的成员变量与方法
java接口中变量的默认修饰符为 public static final int i = 3; 相当于 public static final int i = 3; java接口中方法的默认修饰符为 ...