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编程练习的更多相关文章

  1. Flink 编程接口

    欢迎来 kk大数据,今天分享的是 Flink 提供了哪些编程接口可以给我们开发. 一.数据集类型 现实世界中,所有的数据都是以流式的形态产生的,不管是哪里产生的数据,在产生的过程中都是一条条地生成,最 ...

  2. <译>Flink编程指南

    Flink 的流数据 API 编程指南 Flink 的流数据处理程序是常规的程序 ,通过再流数据上,实现了各种转换 (比如 过滤, 更新中间状态, 定义窗口, 聚合).流数据可以来之多种数据源 (比如 ...

  3. Flink 编程模型

    抽象层次   levels_of_abstraction 最低级的抽象接口是状态化的数据流接口(stateful streaming).这个接口是通过 ProcessFunction 集成到 Data ...

  4. 第03讲:Flink 的编程模型与其他框架比较

    Flink系列文章 第01讲:Flink 的应用场景和架构模型 第02讲:Flink 入门程序 WordCount 和 SQL 实现 第03讲:Flink 的编程模型与其他框架比较 本课时我们主要介绍 ...

  5. Flink学习笔记:Flink API 通用基本概念

    本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKhaz ...

  6. flink学习笔记-各种Time

    说明:本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKh ...

  7. 首次尝试Flink的一些感受

    最近打算研究研究 Flink,根据官方文档写个 Hello,World.入门还是比较容易的,不需要复杂的安装环境.配置.这篇文章简单介绍 Flink 的使用感受以及入门. 感受 搭建环境方便:Flin ...

  8. Flink入门宝典(详细截图版)

    本文基于java构建Flink1.9版本入门程序,需要Maven 3.0.4 和 Java 8 以上版本.需要安装Netcat进行简单调试. 这里简述安装过程,并使用IDEA进行开发一个简单流处理程序 ...

  9. Flink入门介绍

    什么是Flink Apache Flink是一个分布式大数据处理引擎,可以对有限数据流和无限数据流进行有状态计算.可部署在各种集群环境,对各种大小的数据规模进行快速计算. Flink特性 支持高吞吐. ...

随机推荐

  1. 网络编程 - 简单的socket例子

    1.客户端 #客户端import socketclient=socket.socket() #生成socket连接对象client.connect(("localhost",696 ...

  2. Linux 安装 Tomcat 详解

    说明:安装的 tomcat 为解压版(即免安装版):apache-tomcat-8.5.15.tar.gz (1)使用 root 用户登录虚拟机,在根目录下的 opt 文件夹新建一个 software ...

  3. msdn的原版windows下载地址链接

    http://msdn.itellyou.cn/ 所有版本的下载地址 进去点左边操作系统

  4. Random和ArrayList的应用

    /*Random类应用与Math类应用,创建一个类, * 1)分别用Random类和Math.random()方法生成随机数. * 2) 把Math.random()方法生成的随机数,转换成1-100 ...

  5. top Universities in Mechanical Engineering

  6. jmeter 性能测试

    1. Ramp-up Period(in seconds)代表多长时间内启动所有线程 2. Aggregate Report Samples:总共发给服务器的请求数量 Average:单个请求的平均响 ...

  7. BNUOJ 5966 Rank of Tetris

    Rank of Tetris Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ...

  8. 洛谷—— P2176 [USACO14FEB]路障Roadblock

    https://www.luogu.org/problem/show?pid=2176 题目描述 每天早晨,FJ从家中穿过农场走到牛棚.农场由 N 块农田组成,农田通过 M 条双向道路连接,每条路有一 ...

  9. P1082||T1200 同余方程 codevs|| 洛谷

     时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   http://codevs.cn/problem/1200/||https://www.luogu.o ...

  10. Ubuntu 16.04下轻量级文件搜索工具Catfish

    Catfish搜索文件速度快,但是不支持正则表达式. 安装: sudo add-apt-repository ppa:catfish-search/ppa sudo apt-get update su ...