SparkStreaming 4个实用Demo的详细记录


本文将会介绍四个Demo案例,分别是updateStateByKey算子的使用,SparkStreaming写入mysql,窗口函数的使用和黑名单的过滤,然后会将代码分享到github
github地址: https://github.com/2NaCl/spark-demo.git

目标一:updateStateByKey算子的使用

首先我们先看看官网对于这个算子的介绍:

在这里插入图片描述
大意是,此算子可以在保持任意状态下去更新信息,但是有两个要求:

  1. 所谓的状态可以是任意类型
  2. 要定义状态的更新,要用函数指定更新前的状态和更新后的状态

然后就来像文档所说,举一个例子套用这个算子说明其意义。

需求:统计到目前为止累积出现的单词的个数(需要保持以前的状态)

思路:

  1. 首先配置好sparkConf和StreamingContext,每五秒统计一次
    在这里插入图片描述

  2. 利用socket通信,监控一个端口
    在这里插入图片描述

  3. 对端口输入进来的数据进行自定义的过滤
    在这里插入图片描述

  4. 然后使用updateStateByKey,将每次输入的数据按照旧值进行更新
    在这里插入图片描述
    调用的这个函数,我们参照一个官网的案例

在这里插入图片描述
意思就是说,要维护文本数据流中看到的每个单词的运行计数(也就现在这个状态),在这里,运行状态是一个int类型的,它会 自动给输入的字段进行更新函数的调用,传入进来的Seq举个例子就是(a,1)(b,1)这样的,他会给你记录下来,然后你要怎么做看你,但是不管你的操作如何,他都会执行runningCount,把旧的序列进行聚合操作,但是为什么新数据是Seq属性,老数据是Option呢,因为也许我们这里会产生新的值,那么老的值肯定就不存在,是null,所以要用Option,这个Demo为了演示方便,所以直接用的.sum
在这里插入图片描述
我们可以看到,老数据执行的是getOrElse(0),这就是因为我们不确定是否以前是否是存在的。

  1. 注意:因为我们使用的算子是stateful类型的,所以要用streamingContext声明一个checkpoint,这个我不知道为啥,反正官网这么写的
    在这里插入图片描述

代码在最上方github里,有兴趣可以自己clone一下跑着玩玩

目标二:计算累积出现的单词个数写入mysql

代码还用上面的,这个目标二单纯只做写入操作,上面说的很详细了,可以好好理解的,不行可以看官网。

这里会用到一个Foreach操作,也是先来看文档

在这里插入图片描述
大意是说:这个算子作用于一个函数通过流产生的每一个RDD,然后推送到外部系统,基本都用于流操作中。
然后说几点注意的地方,也是官网提示的
在这里插入图片描述
大意就是:不要在Spark驱动程序中创建连接对象,然后尝试在Spark工作程序中使用它来保存RDD中的记录,不然会出问题,也就是这样:
在这里插入图片描述
这肯定是不对的,会产生序列化错误的,因为工作的地方和连接产生的地方不同,正确的方法是在worker创建连接,但是这又会产生另一个问题:
在这里插入图片描述
我们确实做到了在工作的地方建立连接,但是相对的又会产生很多资源消耗,所以我们就要使用 rdd.foreachPartition用一个连接,推送一个分区内所有的记录
在这里插入图片描述
但是如果我们有的时候需要分开推送,有的推送有的不推送怎么办呢,那么我们就可以使用到连接池技术:
在这里插入图片描述

然后来操作一下我们的程序:
需求:将统计结果写入mysql数据库

思路:

  1. 首先创建一张表

在这里插入图片描述

  1. 建立mysql的连接
    在这里插入图片描述

  2. 使用算子

在这里插入图片描述

  1. 运行输入
    在这里插入图片描述
    在这里插入图片描述

目标三:窗口函数的使用

先来说一下什么是窗口函数,
window定时的进行一个时间段内的数据处理
首先还是先来看官方文档

在这里插入图片描述
大意是 在固定时间范围的情况下,捕捉该范围的数据进行操作,并且操作之后会滑动一定的时间单位,不断的去进行运算,所以我们使用窗口函数需要制定两个参数:

  1. 窗口长度 - 窗口的持续时间(图中的3)。
  2. 滑动间隔 - 执行窗口操作的间隔(图中的2)。

而且既然我们滑动了,那么就不能有重复计算,所以滑动的记录要求一定得是窗口长度的倍数
举一个官网的例子:
在这里插入图片描述
这就代表每10秒执行前30秒的data,并且除此之外还有一些其他的api,但是所含参数必须要有上面提到的那两个

在这里插入图片描述

目标四:黑名单过滤

我们有两个步骤,第一是使用transform算子,然后就是使用SparkStreaming整合RDD进行操作

思路:

  1. 常规的进行配置
    在这里插入图片描述

  2. 在这里我们手动定义黑名单的姓名,真实环境可以从数据库获取
    在这里插入图片描述

  3. 然后我们将黑名单的List转换成一个map形式的RDD,姓名为key,是否为黑名单定义为true在这里插入图片描述

  4. 还是继续向端口注入消息
    在这里插入图片描述

  5. 最关键的一步,我们需要的是将端口注入的(k,v)形式的消息,拿出value值也就是姓名,拿去判断,因为输入进来的之间有逗号,所以用scala使用.split(",")分开然后取出第二个值,取出输入的姓名之后就要拿去和blackRDD去对比了,所以需要filter操作,这个时候,我们过滤之前的值应该是(<20180808,zs>,<true>),过滤之后的目的就是,只删选出第二个值为true的姓名,然后将姓名重新组合成map

在这里插入图片描述

然后运行
输入
在这里插入图片描述
控制台打印:
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值