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. Python中使用SQLite

    参考原文 廖雪峰Python教程 使用SQLite SQLite是一种嵌入式数据库,它的数据库就是一个文件.由于SQLite本身是用C写的,而且体积很小,所以经常被集成到各种应用程序中,甚至在IOS和 ...

  2. 字符串、散列--P1598 垂直柱状图

    题目描述 写一个程序从输入文件中去读取四行大写字母(全都是大写的,每行不超过100个字符),然后用柱状图输出每个字符在输入文件中出现的次数.严格地按照输出样例来安排你的输出格式. 输入输出格式 输入格 ...

  3. The Falling Leaves(建树方法)

    uva 699 紫书P159 Each year, fall in the North Central region is accompanied by the brilliant colors of ...

  4. [bzoj1044][HAOI2008][木棍分割] (二分+贪心+dp+队列优化)

    Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长 ...

  5. Git——跟踪或取消跟踪文件

    在Git是用过程中,可能遇到以下情况: 1.被跟踪文件里面有不想跟踪的文件. 2.每次用git status查看状态时总是列出未被跟踪的文件. 解决方法: 1.当被跟踪的文件里面有不想跟踪的文件时,使 ...

  6. Maven学习总结(31)——Maven坐标详解

    Maven的一个核心的作用就是管理项目的依赖,引入我们所需的各种jar包等.为了能自动化的解析任何一个Java构件,Maven必须将这些Jar包或者其他资源进行唯一标识,这是管理项目的依赖的基础,也就 ...

  7. Leetcode 92.反转链表

    92.反转链表 反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明:1 ≤ m ≤ n ≤ 链表长度. 示例: 输入: 1->2->3->4->5->NULL ...

  8. TCP/IP协议1

    1.分层 应用层 telent 远程登录,ftp 文件传输协议,smtp 简单邮件传送协议 snmp 简单网络管理协议 email 运输层  tcp(提供可靠的数据通信)和udp(数据报的分组从一台主 ...

  9. linux安装java mysql tomcat 环境

    安装jdk: 1. 查看系统版本 uname -a 2.查看操作系统 cat  /proc/version 3.上传安装文件到指定目录   tar -zxvf jdkxxx. 4.修改配置文件  vi ...

  10. Eddy's mistakes

    Problem Description Eddy usually writes  articles ,but he likes mixing the English letter uses, for ...