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特性 支持高吞吐. ...
随机推荐
- java jvm eclipse 性能调优
低配配置 -Dfile.encoding=UTF-8-Xms960m-Xmx960m-Xmn384m-Xverify:none-Xss256k-XX:MaxTenuringThreshold=2-XX ...
- python学习,使用requests库来模拟登录github,post请求。
这次我们要模拟登录的页面是 https://github.com/login 首先我们先尝试着登陆一遍分析一下请求, 打开开发者工具下的network选项, 可以很清楚的看到这个会话session,而 ...
- LINUX-磁盘空间
df -h 显示已经挂载的分区列表 ls -lSr |more 以尺寸大小排列文件和目录 du -sh dir1 估算目录 'dir1' 已经使用的磁盘空间' du -sk * | sort -rn ...
- BC in fluent
Boundary conditions in Fluent Table of Contents 1. Boundary Conditions (BC) 1.1. Turbulence Paramete ...
- Divide Groups 二分图的判定
Divide Groups Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- 【03】WAMPServer集成环境下载和安装
WAMPServer集成环境下载和安装1.W:windows,A:Apache,M:MySQL,P:PHP2.下载WAMP开发包网址:www.wampserver.com 3.安装 ...
- ceph 简介
Ceph 存储集群 数据的存储 伸缩性和高可用性 CRUSH 简介 集群运行图 高可用监视器 高可用性认证 智能程序支撑超大规模 动态集群管理 关于存储池 PG 映射到 OSD 计算 PG ID 互联 ...
- Leetcode 89.格雷编码
格雷编码 格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异. 给定一个代表编码总位数的非负整数 n,打印其格雷编码序列.格雷编码序列必须以 0 开头. 示例 1: 输入: 2 ...
- Navicat使用技巧
1.有时按快捷键Ctrl+F搜某条数据的时候搜不到,但是能用sql查出来,这是怎么回事? Ctrl+F只能搜本页数据,不在本页的数据搜不到,navicat每页只显示1000条数据.在数据多的时候nav ...
- Neo4j ETL工具快速上手:简化从关系数据库到图数据库的数据迁移
注:本文系从https://medium.com/neo4j/tap-into-hidden-connections-translating-your-relational-data-to-graph ...