基本概念
状态流每条流过的数据和前面的数据有关系
无状态流类时Storm就是无状态的计算框架,每一条消息来了以后和前后都没有关系,一条是一条
宽依赖父RDD的每个分区都回最多被子类的一个RDD所使用
窄依赖父RDD的每个分区会被多个子类的RDD分区所使用
dataset 和datastream 区别
1.keyBy = groupBy() 根据key的hash值进行分组聚合
datastream
spark streaming 中不管有没有数据,都是按照时间进行分批处理,显示的结果是目前批次的;flink datastream 没有数据就不会进行处理且结果显示所有以前的数据。
event time 事件时间延迟高缓存较大,ingestion time摄取时间,延迟折中,processing time 不需缓存,延迟最小
map 保持元素的分区和排序
不同类型流转换关系
DataStream=>keyedStream=>windowedStream=>DataStream=>sink
窗口操作
1.Tumbling Time window
[12:01-12:05]->[12:06-12:10]
2.Sliding Time Window
[12:01-12:05]->[12:02-12:06]->[12:03-12:07]
3.Session Time Window
通过不活动的时间来区分IM
时间和水位线
Watermark是Flink插入到数据流中的一种特殊的数据结构,它包含一个时间戳,并假设后续不会有小于该时间戳的数据。Watermark机制允许用户来控制准确度和延迟。Watermark设置得与事件时间戳相距紧凑,会产生不少迟到数据,影响计算结果的准确度,整个应用的延迟很低;Watermark设置得非常宽松,准确度能够得到提升,但应用的延迟较高,因为Flink必须等待更长的时间才进行计算。
周期性水位线 BoundedOutOfOrdernessTimestampExtractor 和AssignerWithPeriodicWatermarks
逐个式的水位线 AssignerWithPunctuatedWatermarks
递增水位线 AscendingTimestampExtractor
乱序水位线和windowfunctio的触发关系
wartermark时间=eventtime-watermark时间
1、watermark时间 >= window_end_time(对于out-of-order以及正常的数据而言)
2、在[window_start_time,window_end_time)中有数据存在
# watermark 2s, 翻滚窗口 3s
val senv=StreamExecutionEnvironment.getExecutionEnvironment
senv.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
val stream=senv.socketTextStream("192.168.0.100",9999)
.assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor[String](Time.seconds(2)) {
override def extractTimestamp(t: String): Long = {
val eventTime=t.split(" ")(0).toLong
println(s"$eventTime")
eventTime
}
}).map(x=>(x.split(" ")(1),1L))
.keyBy(0)
//滚动窗口
stream.window(TumblingEventTimeWindows.of(Time.seconds(3)))
.sum(1).print()
输入 | (1000 a) | (2000 a ) | (3000 a) | (4000 a ) | (5000 a) | (6000 a) | (7000 a ) | (8000 a ) | (10000 a) | (15000 a) |
---|---|---|---|---|---|---|---|---|---|---|
输出 | 1000 | 2000 | 3000 | 4000 | 5000 3> (a,2) | 6000 | 7000 | 8000、 3> (a,3) | 10000 | 15000、 3> (a,3) 、3> (a,1) |
触发的条件时间,就是窗口反转的到的窗口边界。
#滑动窗口4s,2s一滑 水位线2s
stream.window(SlidingEventTimeWindows.of(Time.seconds(4),Time.seconds(2)))
.sum(1).print()
输入 | (1000 a) | (2000 a ) | (3000 a) | (4000 a ) | (6000 a) | (7000 a) ,(7100 a ),(7200 a ),(7500 a ) | (8000 a) | (11000 a) |
---|---|---|---|---|---|---|---|---|
输出 | 1000 | 2000 | 3000 | 4000 ,3> (a,1) | 6000 , 3>(a,3) | 7000,7100,7200,7500 | 8000、 3> (a,3) | 11000、 3> (a,6) ) |
触发条件的时间,正是窗口右边界要滑到的时间边界。
#会话窗口4s,水位线2s
stream.window(EventTimeSessionWindows.withGap(Time.seconds(4)))
.sum(1).print()
输入 | (1000 a) | (3000 a) | (7000,a) | (11000,a) | (16000,a) | (22000,a) | (26000,a) | (31000,a) | (36000,a ) | (37000,a) |
---|---|---|---|---|---|---|---|---|---|---|
输出 | 1000 | 3000 | 7000 | 11000 | 16000 | 22000,(a,4)(a,1) | 26000 | 31000 | 36000 ,(a,2) | 37000,(a,1 ) |
触发条件的时间,要是大于上次会话的时间+4
dataset
map 一个元素产生一个元素
flatmap 一个元素产生零个、一个或者多个元素
MapPartition 分区数据合成一个iterator
Aggregate 聚合函数,聚合一组值成一个单独元素
Cross 两个数据源产生笛卡尔积
union 合共两个数据源
import org.apache.flink.api.common.operators.Order
import org.apache.flink.api.java.aggregation.Aggregations
import org.apache.flink.api.scala.ExecutionEnvironment
import org.apache.flink.core.fs.FileSystem.WriteMode
import org.apache.flink.api.scala._ # 导入进行隐式转换
val env=ExecutionEnvironment.getExecutionEnvironment
val text= env.readTextFile("data.txt") #类型 key values 例如hadoop java
val counts = text.
flatMap { _.toLowerCase.split("\\W+").filter { _.nonEmpty } }
.map { (_, 1) }
.groupBy(0)
# .aggregate(Aggregations.SUM,1)
.sum(1)
.sortPartition(1,Order.DESCENDING) # 分区排序
.setParallelism(2) # 是2会产生2个输出文件,1会产生一个输出文件
counts.writeAsCsv("write.txt","\n","\t", WriteMode.OVERWRITE)
env.execute("word count job")
Broadcast Variables
广播变量,分布在每一个节点上,数据量尽量小。
Distributed Cache
分布式缓存,可以存储数据文件或者机器学习模型
富函数
它与常规函数的不同在于,可以获取运行环境的上下文,并拥有一些生命周期方法,所以可以实现更复杂的功能。例如open, close, getRuntimeContext, and setRuntimeContext等功能。适用于accumulators and counters
Accumulators & Counters
累加器和计数器