Spark(十) -- Spark Streaming API编程
本文测试的Spark版本是1.3.1
Spark Streaming编程模型:
第一步:
需要一个StreamingContext对象,该对象是Spark Streaming操作的入口 ,而构建一个StreamingContext对象需要两个参数:
1、SparkConf对象:该对象是配置Spark 程序设置的,例如集群的Master节点,程序名等信息
2、Seconds对象:该对象设置了StreamingContext多久读取一次数据流
第二步:
构建好入口对象之后,直接调用该入口的方法读取各种不同方式传输过来的数据流,如:Socket,HDFS等方式。并会将数据转换成DStream对象进行统一操作
第三步:
DStream本身是一种RDD序列,Streaming接受数据流之后会进行切片,每个片都是一个RDD,而这些RDD最后都会包装到一个DStream对象中统一操作。在这个步骤中,进行对数据的业务处理
第四步:
调用入口对象的start和awaitTermination开始读取数据流
下面分别使用不同的Spark Streaming 处理方式完成WordCount单词计数
HDFS文件测试
object HDFSWordCount {
def main(args: Array[String]) {
//参数设置
if (args.length < 2) {
System.err.println("Usgae : <spark master> <hdfs path>")
System.exit(1)
}
//第一步:创建StreamingContext入口
val sparkConf = new SparkConf().setMaster(args(0)).setAppName("HDFSWordCount")
val streaming = new StreamingContext(sparkConf,Seconds(10))
//第二步:调用textFileStream读取指定路径的文件
val data = streaming.textFileStream(args(1))
//第三步,数据业务处理
//使用flatMap将数据map之后的分切压成一个DStream
val words = data.flatMap(_.split(" "))
val wordCount = words.map(x => (x,1)).reduceByKey(_+_)
wordCount.print()
//第四步
streaming.start()
streaming.awaitTermination()
}
Socket数据流测试
object NetworkWordCount {
def main(args: Array[String]) {
if (args.length < 3) {
System.err.println("Usage : <spark master> <hostname> <port>")
System.exit(1)
}
val sparkConf = new SparkConf().setMaster(args(0)).setAppName("NetworkWordCount")
val streaming = new StreamingContext(sparkConf,Seconds(10))
//参数:1、主机名;2、端口号;3、存储级别
val data =
streaming.socketTextStream(args(1),args(2).toInt,StorageLevel.MEMORY_AND_DISK_SER)
val words = lines.flatMap(_.split(" "))
val wordCount = words.map(x => (x, 1)).reduceByKey(_ + _)
wordCount.print()
streaming.start()
streaming.awaitTermination()
}
可以看到,对于同一中业务处理逻辑来说,不同的数据来源只要调用不同的方法接收即可,转换成DStream之后的处理步骤是一模一样的
下面的代码时配合测试Socket数据的,使用java命令执行jar包,传入参数:1、端口号;2、产生数据的频率(毫秒)
即可在指定的端口上产生数据提供Spark Streaming接收
package Streaming
import java.net.ServerSocket
import java.io.PrintWriter
object Logger {
def generateContent(index: Int): String = {
import scala.collection.mutable.ListBuffer
val charList = ListBuffer[Char]()
for (i <- 65 to 90) {
charList += i.toChar
}
val charArray = charList.toArray
charArray(index).toString()
}
def index = {
import java.util.Random
val ran = new Random
ran.nextInt(7)
}
def main(args: Array[String]): Unit = {
if (args.length != 2) {
System.err.println("Usage:<port> <millisecond>")
System.exit(1)
}
val listener = new ServerSocket(args(0).toInt)
while (true) {
val socket = listener.accept()
new Thread() {
override def run = {
println("Get client connected from:" + socket.getInetAddress)
val out = new PrintWriter(socket.getOutputStream(), true)
while (true) {
Thread.sleep(args(1).toLong)
val content = generateContent(index)
println(content)
out.write(content + '\n')
out.flush()
}
socket.close()
}
}.start()
}
}
}
在上述的例子中,文中使用的是Seconds(10)
也就是说每10秒钟处理一次数据
第一个10秒处理的结果是不会影响到第二个10秒的
但是有时候我们需要进行汇通统计,要用到之前几个10秒阶段的数据怎么办?
这里要用到一个updateStateByKey方法,该方法会保存上次计算数据的状态,以供下次计算使用。
上代码:
object StatefulWordCount {
def main(args: Array[String]) {
if (args.length < 3) {
System.err.println("Usage : <spark master> <hostname> <port>")
System.exit(1)
}
//定义一个匿名函数,并赋值给updateFunc
//该函数是updateStateByKey方法的参数,该方法要求传入一个匿名参数且参数格式为values:Seq[Int],state:Option[Int]
//其中values是当前的数据,state表示之前的数据
//这个匿名函数的作用就是将各个10秒阶段的结果累加汇总
val updateFunc = (values:Seq[Int],state:Option[Int]) => {
val now = values.foldLeft(0)(_+_)
val old = state.getOrElse(0)
Some(now + old)
}
val conf = new SparkConf().setAppName("StatefulWordCount").setMaster(args(0))
val streaming = new StreamingContext(conf, Seconds(10))
//checkpoint会将数据放在指定的路径上,这个操作是必须的,为了保护数据,如果不设置会报异常
streaming.checkpoint(".")
val lines = streaming.socketTextStream(args(1), args(2).toInt, StorageLevel.MEMORY_AND_DISK_SER)
val words = lines.flatMap(_.split(" "))
val wordDStream = words.map(x => (x, 1))
//在这里将updateFunc传入
val stateDStream = wordDStream.updateStateByKey(updateFunc)
stateDStream.print()
streaming.start()
streaming.awaitTermination()
}
在Spark Streaming中还有一个window的概念,即滑动窗体
下图是官方文档中给出的解释:
使用滑动窗体要设置两个指定参数:
1、窗体长度
2、滑动时间
例如,设置一个窗体长度为5,滑动时间为2,意味着,每2秒处理上一个5秒内的数据流
这样的处理可以应用在例如微博统计最热搜索词
每2秒钟统计一次过去5秒内的最热搜索词
统计最热搜索词实例代码:
object WindowWordCount {
def main(args: Array[String]) {
if (args.length < 3) {
System.err.println("Usage : <spark master> <hostname> <port> <Streaming Seconds> <Window Seconds> <Slide Seconds>")
System.exit(1)
}
val conf = new SparkConf().setAppName("WindowWordCount").setMaster(args(0))
val streaming = new StreamingContext(conf, Seconds(args(3).toInt))
//checkpoint会将数据放在指定的路径上,这个操作是必须的,为了保护数据,如果不设置会报异常
streaming.checkpoint(".")
val lines = streaming.socketTextStream(args(1), args(2).toInt, StorageLevel.MEMORY_ONLY)
val words = lines.flatMap(_.split(" "))
//map操作之后数据的格式为:
//(a,1)(b,1)...(n,1)格式
//调用reduceByKeyAndWindow替代普通的reduceByKey
//最后两个参数分别是窗体长度和滑动时间
val wordCount = words.map(x => (x, 1)).reduceByKeyAndWindow(_ + _, _ - _, Seconds(args(4).toInt),
Seconds(args(5).toInt))
//对结果进行降序排序
//由于DStream本身不具备RDD的一些操作,调用transform方法可以让RDD的一些操作(例如sortByKey等)作用在其之上,返回的仍然是一个DStream对象
val sorted = wordCount.map { case (char, count) => (count, char) }.transform(_.sortByKey(false)).map
{ case (count, char) => (char, count) }
sorted.print()
streaming.start()
streaming.awaitTermination()
}
}
reduceByKeyAndWindow有两种使用方法:
1、educeByKeyAndWindow(_ + _, Seconds(5),seconds(1))
2、reduceByKeyAndWindow(_ + , - _, Seconds(5),seconds(1))
二者的区别见下图:
第一种是简单粗暴的直接累加
而第二种方式就显得比较文雅和高效了
例如现在计算t+4的累积数据
第一种方式是,直接从t+…+(t+4)
第二种处理为,用已经计算好的(t+3)的数据加上(t+4)的数据,在减去(t-1)的数据,就可以得到和第一种方式一样的结果,但是中间复用了三个数据(t+1,t+2,t+3)
以上为Spark Streaming API的简单使用
Spark(十) -- Spark Streaming API编程的更多相关文章
- Spark Streaming的编程模型
Spark Streaming的编程和Spark的编程如出一辙,对于编程的理解也非常类似.对于Spark来说,编程就是对于RDD的操作:而对于Spark Streaming来说,就是对DStream的 ...
- 利用SparkLauncher 类以JAVA API 编程的方式提交Spark job
一.环境说明和使用软件的版本说明: hadoop-version:hadoop-2.9.0.tar.gz spark-version:spark-2.2.0-bin-hadoop2.7.tgz jav ...
- 03、IDEA下Spark API编程
03.IDEA下Spark API编程 3.1 编程实现Word Count 3.1.1 创建Scala模块 3.1.2 添加maven支持,并引入spark依赖 <?xml version=& ...
- Spark SQL 编程API入门系列之Spark SQL支持的API
不多说,直接上干货! Spark SQL支持的API SQL DataFrame(推荐方式,也能执行SQL) Dataset(还在发展) SQL SQL 支持basic SQL syntax/Hive ...
- 大数据技术之_27_电商平台数据分析项目_02_预备知识 + Scala + Spark Core + Spark SQL + Spark Streaming + Java 对象池
第0章 预备知识0.1 Scala0.1.1 Scala 操作符0.1.2 拉链操作0.2 Spark Core0.2.1 Spark RDD 持久化0.2.2 Spark 共享变量0.3 Spark ...
- Spark 以及 spark streaming 核心原理及实践
收录待用,修改转载已取得腾讯云授权 作者 | 蒋专 蒋专,现CDG事业群社交与效果广告部微信广告中心业务逻辑组员工,负责广告系统后台开发,2012年上海同济大学软件学院本科毕业,曾在百度凤巢工作三年, ...
- spark教程(15)-Streaming
Spark Streaming 是一个分布式数据流处理框架,它可以近乎实时的处理流数据,它易编程,可以处理大量数据,并且能把实时数据与历史数据结合起来处理. Streaming 使得 spark 具有 ...
- Real Time Credit Card Fraud Detection with Apache Spark and Event Streaming
https://mapr.com/blog/real-time-credit-card-fraud-detection-apache-spark-and-event-streaming/ Editor ...
- Spark(1.6.1) Sql 编程指南+实战案例分析
首先看看从官网学习后总结的一个思维导图 概述(Overview) Spark SQL是Spark的一个模块,用于结构化数据处理.它提供了一个编程的抽象被称为DataFrames,也可以作为分布式SQL ...
随机推荐
- Linux终端彩色打印+终端进度条【转】
转自:https://my.oschina.net/jcseg/blog/178047 开发的一个应用程序选择了终端界面, 为了使软件稍微好看些, 研究下Linux终端的彩色打印, 并且基于这个彩色打 ...
- 【bzoj2086】Blocks
在洛谷上点了个Splay的tag想玩玩,结果看到这题…… #include<bits/stdc++.h> #define N 1000005 using namespace std; ty ...
- [ nginx ] 代理后端tomcat 无法显示图片报错:ERR_CONTENT_LENGTH_MISMATCH
问题日志如下:
- require.js模块化管理和加载js(按需加载)简单实例教学
一.为什么要用require.js? 最早的时候,所有Javascript代码都写在一个文件里面,只要加载这一个文件就够了.后来,代码越来越多,一个文件不够了,必须分成多个文件,依次加载.下面的网页代 ...
- 《Java编程思想》笔记 第八章 多态
1.向上转型 把子类引用当作父类引用.(子类对象赋值给父类引用) 2.绑定 确定方法属于哪个类. 3.前期绑定 程序执行前绑定. 4.后期绑定也叫动态绑定 程序运行时绑定. 5.多态 多个不同的对象对 ...
- 前端工程师必备PS技能
PS参考线及其辅助 视图-->新建参考线 也可以快捷键Ctrl+R,显示区的上侧和左侧就会出现标尺.任意点选中,并拖动标尺,便会出现浅蓝色的辅助线.只有在移动工具下,才能拖动某一条参考线. 删除 ...
- Python 进阶 之 else块 巧(慎)用
Python 的 else 模块和其他语言的else模块相比有那么一丢丢的特殊用法,有些用法虽然不推荐用,但是别人如果用了,最起码能看懂是不是? 1:快捷返回值: 格式: value1 if expr ...
- redis设置慢查询日志
Redis 的慢查询日志功能用于记录执行时间超过给定时长的命令请求, 用户可以通过这个功能产生的日志来监视和优化查询速度. 1.redis生命周期 慢查询发生在第3阶段 2.两个配置 2.1.slow ...
- 20180824Noip模拟赛10分总结
嗯,总之,是我太傻了. 我真傻,真的,我单知道最小生成树,却不知道还有最大生成树 T1 最大生成树.... 累加每一个环内,最大生成树的边权,(对环求最大生成树,则必然剩下一个边权最小的边(因为是求生 ...
- 5、Django实战第5天:首页和登录页面的配置
从这天开始我们需要用到前端源码,需要的朋友可以进行小额打赏(15元),打赏二维码在博客的右侧,打赏后可以凭截图联系463951510@qq.com,博主收到邮件后会立即回复发送所有源码素材,实战过程中 ...