Flink编程练习
1.wordcount
利用socket作为数据源,对输入的每行数据进行单词计数。计算频率为process time的每10秒一次,结果输出到terminal。
object SocketWindowWordCount {
def main(args: Array[String]) : Unit = {
val port: Int = try {
ParameterTool.fromArgs(args).getInt("port")
} catch {
case e: Exception => {
System.err.println("No port specified. Please run 'xx.jar --port <port>'")
return
}
}
val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
val text = env.socketTextStream("localhost", port, '\n')
val windowCounts = text
.flatMap(_.split("\\s"))
.map(WordWithCount(_,1))
.keyBy(_.word)
.window(TumblingProcessingTimeWindows.of(Time.seconds(10)))
.sum("count")
windowCounts.print()
env.execute("Socket Window WordCount")
}
case class WordWithCount(word: String, count: Long)
}
数据格式
case class SensorReading(id: String, timestamp: Long, temperature: Double)
object SmokeLevel extends Enumeration {
type SmokeLevel = SmokeLevel.Value
val High, Low = Value
}
case class Alert(message: String, timestamp: Long)
2.双流警报EventTime
时间特征为event time,每1s更新一次watermark,watermark由SensorReading内部的timestamp推进,允许5s的延迟(过滤掉迟到数据)。数据源SensorReading并发处理,数据源SmokeLevel并发度为1,但能够被每个并发的SensorReading流访问。假设两个流的数据是源源不断的。当SensorReading的temperature大于100且SmokeLevel为High时触发警报。警报包含当时SensorReading的timestamp。
下面例子,迟到数据,即数据晚于WM依然会被处理
注意:如果某个流在connect前assignTimestampsAndWatermarks,connect后的流是不会更新WM的。
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
env.getConfig.setAutoWatermarkInterval(1000L)
val sensorInput = env
.addSource(new SensorSource)
.assignTimestampsAndWatermarks(
new BoundedOutOfOrdernessTimestampExtractor[SensorReading](Time.seconds(5)) {
override def extractTimestamp(element: SensorReading): Long = {
element.timestamp
}
})
val smokeLevelInput = env
.addSource(new SmokeLevelSource)
.setParallelism(1)
val res = sensorInput
.process(new MyKeyedProcessFunction) // 这里的实现省略,其实就是if和collect
.connect(smokeLevelInput)
.flatMap(new MyFlatMapFunc)
res.print()
env.execute("multiple streamss")
}
class MyFlatMapFunc extends CoFlatMapFunction[SensorReading, SmokeLevel, Alert] {
private private var curSmokeLevel = SmokeLevel.Low
override def flatMap1(value: SensorReading, out: Collector[Alert]): Unit = {
if (curSmokeLevel.equals(SmokeLevel.High) && value.temperature > 100) {
out.collect(Alert("Alert! ", value.timestamp))
}
}
override def flatMap2(value: SmokeLevel, out: Collector[Alert]): Unit = {
curSmokeLevel = value
}
}
3.持续计数stateful + timer + SideOutputs
对每个key的数据量进行累加计数,如果1分钟没有新数据,就输出key-count对。对每一个数据进行处理时,sideoutput当前所处理的key的state数据(更新后的)
val realTimeInfo: OutputTag[String] =
new OutputTag[String]("real-time_info")
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.getConfig.setAutoWatermarkInterval(1000L)
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
val countStream = env.addSource(new SensorSource)
.keyBy(_.id)
.process(new MyProcessFunc)
countStream.getSideOutput(realTimeInfo)
.print()
env.execute()
}
case class CountWithTimeStamp(key: String, count: Int, ts: Long)
class MyProcessFunc extends KeyedProcessFunction[String, SensorReading, (String, Int)] {
lazy val state = getRuntimeContext
.getState(new ValueStateDescriptor[CountWithTimeStamp]("muState", classOf[CountWithTimeStamp]))
override def processElement(value: SensorReading,
ctx: KeyedProcessFunction[String, SensorReading, (String, Int)]#Context,
out: Collector[(String, Int)]): Unit = {
val current = state.value() match {
case null =>
CountWithTimeStamp(value.id, 1, ctx.timestamp())
case CountWithTimeStamp(key, count, lastModified) =>
// 删除上一次的timer
ctx.timerService().deleteEventTimeTimer(lastModified + 6000)
CountWithTimeStamp(key, count + 1, ctx.timestamp())
}
state.update(current)
ctx.timerService().registerEventTimeTimer(current.ts + 6000)
ctx.output(realTimeInfo, current)
}
override def onTimer(timestamp: Long,
ctx: KeyedProcessFunction[String, SensorReading, (String, Int)]#OnTimerContext,
out: Collector[(String, Int)]): Unit = {
state.value() match {
case CountWithTimeStamp(key, count, lastModified) =>
if (timestamp == lastModified) out.collect((key, count)) else None
case _ =>
}
}
}
4.一定时间范围内的极值windowfunction + checkpoint
利用tumbling window计算各个sensor在15s内的最大最小值,返回结果包含窗口的结束时间。另外,window只存储极值,不保留原数据。
checkpoint间隔为10s,watermark刷新间隔1s
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.getConfig.setAutoWatermarkInterval(1000)
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
env.enableCheckpointing(10 * 1000L)
env.addSource(new SensorSource)
.assignTimestampsAndWatermarks(new MyPeriodicAssigner)
.map(r => (r.id, r.temperature, r.temperature))
.keyBy(_._1)
.window(TumblingEventTimeWindows.of(Time.seconds(15)))
.reduce(
(item1: (String, Double, Double), item2: (String, Double, Double)) => {
(item1._1, item1._2.min(item2._2), item1._3.max(item2._3))
},
new MyWindowEndProcessFunction()
)
}
case class MaxMinTemperature(key: String, min: Double, max: Double, ts: Long)
class MyWindowEndProcessFunction
extends ProcessWindowFunction[(String, Double, Double), MaxMinTemperature, String, TimeWindow] {
override def process(key: String, context: Context, elements: Iterable[(String, Double, Double)],
out: Collector[MaxMinTemperature]): Unit = {
out.collect(MaxMinTemperature(key, elements.head._2, elements.head._3, context.window.getEnd))
}
}
Flink编程练习的更多相关文章
- Flink 编程接口
欢迎来 kk大数据,今天分享的是 Flink 提供了哪些编程接口可以给我们开发. 一.数据集类型 现实世界中,所有的数据都是以流式的形态产生的,不管是哪里产生的数据,在产生的过程中都是一条条地生成,最 ...
- <译>Flink编程指南
Flink 的流数据 API 编程指南 Flink 的流数据处理程序是常规的程序 ,通过再流数据上,实现了各种转换 (比如 过滤, 更新中间状态, 定义窗口, 聚合).流数据可以来之多种数据源 (比如 ...
- Flink 编程模型
抽象层次 levels_of_abstraction 最低级的抽象接口是状态化的数据流接口(stateful streaming).这个接口是通过 ProcessFunction 集成到 Data ...
- 第03讲:Flink 的编程模型与其他框架比较
Flink系列文章 第01讲:Flink 的应用场景和架构模型 第02讲:Flink 入门程序 WordCount 和 SQL 实现 第03讲:Flink 的编程模型与其他框架比较 本课时我们主要介绍 ...
- Flink学习笔记:Flink API 通用基本概念
本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKhaz ...
- flink学习笔记-各种Time
说明:本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKh ...
- 首次尝试Flink的一些感受
最近打算研究研究 Flink,根据官方文档写个 Hello,World.入门还是比较容易的,不需要复杂的安装环境.配置.这篇文章简单介绍 Flink 的使用感受以及入门. 感受 搭建环境方便:Flin ...
- Flink入门宝典(详细截图版)
本文基于java构建Flink1.9版本入门程序,需要Maven 3.0.4 和 Java 8 以上版本.需要安装Netcat进行简单调试. 这里简述安装过程,并使用IDEA进行开发一个简单流处理程序 ...
- Flink入门介绍
什么是Flink Apache Flink是一个分布式大数据处理引擎,可以对有限数据流和无限数据流进行有状态计算.可部署在各种集群环境,对各种大小的数据规模进行快速计算. Flink特性 支持高吞吐. ...
随机推荐
- 网络编程 - 简单的socket例子
1.客户端 #客户端import socketclient=socket.socket() #生成socket连接对象client.connect(("localhost",696 ...
- Linux 安装 Tomcat 详解
说明:安装的 tomcat 为解压版(即免安装版):apache-tomcat-8.5.15.tar.gz (1)使用 root 用户登录虚拟机,在根目录下的 opt 文件夹新建一个 software ...
- msdn的原版windows下载地址链接
http://msdn.itellyou.cn/ 所有版本的下载地址 进去点左边操作系统
- Random和ArrayList的应用
/*Random类应用与Math类应用,创建一个类, * 1)分别用Random类和Math.random()方法生成随机数. * 2) 把Math.random()方法生成的随机数,转换成1-100 ...
- top Universities in Mechanical Engineering
- jmeter 性能测试
1. Ramp-up Period(in seconds)代表多长时间内启动所有线程 2. Aggregate Report Samples:总共发给服务器的请求数量 Average:单个请求的平均响 ...
- BNUOJ 5966 Rank of Tetris
Rank of Tetris Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ...
- 洛谷—— P2176 [USACO14FEB]路障Roadblock
https://www.luogu.org/problem/show?pid=2176 题目描述 每天早晨,FJ从家中穿过农场走到牛棚.农场由 N 块农田组成,农田通过 M 条双向道路连接,每条路有一 ...
- P1082||T1200 同余方程 codevs|| 洛谷
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond http://codevs.cn/problem/1200/||https://www.luogu.o ...
- Ubuntu 16.04下轻量级文件搜索工具Catfish
Catfish搜索文件速度快,但是不支持正则表达式. 安装: sudo add-apt-repository ppa:catfish-search/ppa sudo apt-get update su ...