在Spark Streaming程序中,若需要使用有状态的流来统计一些累积性的指标,比如各个商品的PV。简单的代码描述如下,使用mapWithState()算子:

val productPvStream = stream.mapPartitions(records => {
var result = new ListBuffer[(String, Int)]
for (record <- records) {
result += Tuple2(record.key(), 1)
}
result.iterator
}).reduceByKey(_ + _).mapWithState(
StateSpec.function((productId: String, pv: Option[Int], state: State[Int]) => {
val sum = pv.getOrElse(0) + state.getOption().getOrElse(0)
state.update(sum)
(productId, sum)
})).stateSnapshots()

PV并不是一直累加的,而是每天归零,重新统计数据。要达到在凌晨0点清除状态的目的,有以下两种方法。

编写脚本重启Streaming程序:

用crontab、Azkaban等在凌晨0点调度执行下面的Shell脚本:

stream_app_name='com.xyz.streaming.MallForwardStreaming'
cnt=`ps aux | grep SparkSubmit | grep ${stream_app_name} | wc -l` if [ ${cnt} -eq 1 ]; then
pid=`ps aux | grep SparkSubmit | grep ${stream_app_name} | awk '{print $2}'`
kill -9 ${pid}
sleep 20
cnt=`ps aux | grep SparkSubmit | grep ${stream_app_name} | wc -l`
if [ ${cnt} -eq 0 ]; then
nohup sh /path/to/streaming/bin/mall_forward.sh > /path/to/streaming/logs/mall_forward.log 2>&1
fi
fi

这种方式最简单,也不需要对程序本身做任何改动。但随着同时运行的Streaming任务越来越多,就会显得越来越累赘了。

给StreamingContext设置超时

在程序启动之前,先计算出当前时间点距离第二天凌晨0点的毫秒数:

def msTillTomorrow = {
val now = new Date()
val tomorrow = new Date(now.getYear, now.getMonth, now.getDate + 1)
tomorrow.getTime - now.getTime
}

然后将Streaming程序的主要逻辑写在while(true)循环中,并且不像平常一样调用StreamingContext.awaitTermination()方法,而改用awaitTerminationOrTimeout()方法,即:

while (true) {
val ssc = new StreamingContext(sc, Seconds(BATCH_INTERVAL))
ssc.checkpoint(CHECKPOINT_DIR) // ...处理逻辑... ssc.start()
ssc.awaitTerminationOrTimeout(msTillTomorrow)
ssc.stop(false, true)
Thread.sleep(BATCH_INTERVAL * 1000)
}

在经过msTillTomorrow毫秒之后,StreamingContext就会超时,再调用其stop()方法(注意两个参数,stopSparkContext表示是否停止关联的SparkContext,stopGracefully表示是否优雅停止),就可以停止并重启StreamingContext。

以上两种方法都是仍然采用Spark Streaming的机制进行状态计算的。如果其他条件允许的话,还可以抛弃mapWithState(),直接借助外部存储自己维护状态。比如将Redis的Key设计为product_pv:[product_id]:[date],然后在Spark Streaming的每个批次中使用incrby指令,就能方便地统计PV了,不必考虑定时的问题。

转载自微信公众号:大数据技术与架构

周期性清除Spark Streaming流状态的方法的更多相关文章

  1. Dream_Spark-----Spark 定制版:005~贯通Spark Streaming流计算框架的运行源码

    Spark 定制版:005~贯通Spark Streaming流计算框架的运行源码   本讲内容: a. 在线动态计算分类最热门商品案例回顾与演示 b. 基于案例贯通Spark Streaming的运 ...

  2. Spark Streaming流式处理

    Spark Streaming介绍 Spark Streaming概述 Spark Streaming makes it easy to build scalable fault-tolerant s ...

  3. Spark之 Spark Streaming流式处理

    SparkStreaming Spark Streaming类似于Apache Storm,用于流式数据的处理.Spark Streaming有高吞吐量和容错能力强等特点.Spark Streamin ...

  4. 5.Spark Streaming流计算框架的运行流程源码分析2

    1 spark streaming 程序代码实例 代码如下: object OnlineTheTop3ItemForEachCategory2DB { def main(args: Array[Str ...

  5. 大数据开发实战:Spark Streaming流计算开发

    1.背景介绍 Storm以及离线数据平台的MapReduce和Hive构成了Hadoop生态对实时和离线数据处理的一套完整处理解决方案.除了此套解决方案之外,还有一种非常流行的而且完整的离线和 实时数 ...

  6. Spark Streaming带状态更新

    带状态的更新是使用的updateStateByKey方法,里面传入一个函数,函数要自己写,注意需要设置checkpoint import org.apache.spark.streaming.kafk ...

  7. 贯通Spark Streaming流计算框架的运行源码

    本章节内容: 一.在线动态计算分类最热门商品案例回顾 二.基于案例贯通Spark Streaming的运行源码 先看代码(源码场景:用户.用户的商品.商品的点击量排名,按商品.其点击量排名前三): p ...

  8. 基于案例贯通 Spark Streaming 流计算框架的运行源码

    本期内容 : Spark Streaming+Spark SQL案例展示 基于案例贯穿Spark Streaming的运行源码 一. 案例代码阐述 : 在线动态计算电商中不同类别中最热门的商品排名,例 ...

  9. spark streaming流式计算---监听器

    随着对spark的了解,有时会觉得spark就像一个宝盒一样时不时会出现一些难以置信的新功能.每一个新功能被挖掘,就可以使开发过程变得更加便利一点.甚至使很多不可能完成或者完成起来比较复杂的操作,变成 ...

随机推荐

  1. SpringBoot异常处理(二)

    参数校验机制 JSR-303 Hibernate 参数接收方式: URL路径中的参数 {id} (@PathVariable(name="id") int-whatever) UR ...

  2. rocketmq 架构设计

    1 消息存储 消息存储是RocketMQ中最为复杂和最为重要的一部分,本节将分别从RocketMQ的消息存储整体架构.PageCache与Mmap内存映射以及RocketMQ中两种不同的刷盘方式三方面 ...

  3. 如何解决 ajax跨域被阻止 CORS 头缺少 'Access-Control-Allow-Origin'的问题?

    已拦截跨源请求:同源策略禁止读取位于 http://192.168.1.72:8080/securityMonitor_TV/service/getTest 的远程资源. (原因:CORS 头缺少 ' ...

  4. 别再费劲去找后台的前端框架了,2021 年就用 Fantastic-admin 吧

    前言 你知道光是基于 Vue 的后台框架在 Github 上有多少个仓库么? 如果你搜索 vue admin 会得到 13120 个仓库,如果用 vue 后台 会得到 7596 个仓库,如果把两者结合 ...

  5. HTML学习案例--仿淘宝商品信息

    步骤:1.布局分析 2.敲代码 考察知识点: 1.类选择器(素材第四天) 2.CSS关于display,padding,margin的应用 3.如何用div布局 总结: 如果想让一行有两组以上的字块, ...

  6. Mybatis-plus的使用步骤

    Mybatis-plus的简单使用步骤 花开堪折直需折,莫待无花空折枝 导入依赖 <dependency> <groupId>org.projectlombok</gro ...

  7. 第12章 DOM操作

    目录 *1. 向DOM中注入HTML 1.1 将HTNL字符串转换成DOM 预处理HTML源字符串 包装HTML 1.2 将DOM元素插入到文档中 2. DOM的特性和属性 通过DOM方法和属性访问特 ...

  8. 【对线面试官】Java NIO

    服务端: public class NoBlockServer { public static void main(String[] args) throws IOException { // 1.获 ...

  9. JVM 源码分析(二):搭建 JDK 8 源码调试环境(Windows 上使用 CLion)

    前言 一.准备源码 二.安装 "Bootstrap JDK" 三.配置编译环境 四.编译与测试 五.安装 CMake 和 GDB 五.准备远程调试 六.开始远程调试 前言 上一篇文 ...

  10. win10中安装Linux子系统

    前言 Win10的Linux子系统闻名已久,今天就来操作一下 正文 限制 该功能是win10 1809 及之后才加入的功能,故请先核对版本. 开启功能 打开windows设置 设置 -> 更新和 ...