flink2

一、流处理API
显示数据类型:.var---->value上specify type
(一)source
(二)Transform【转换算子】
1、简单转换算子【DataStream ->DataStream】:
a、map
b、flatMap:根据旧集合生成一个新的集合
例:
flatMap(List(1,2,3))(i => List(i,i))。结果是List(1,1,2,2,3,3)
List("a b", "c d").flatMap(line => line.split(" "))。结果是List(a, b, c, d) 
c、filter
2、键控(keyed)转换算子:【输入一个值,就会输出一个值】
a、keyby:【DataStream -> KeyedStream】在内部以hash的形式实现的。
b、滚动聚合算子(Rolling Aggregation)【KeyedStream -> DataStream】:sum()、min("id")【只是id字段改变,其他字段不变】、max()、minBy("id")【所有字段都改变】、maxBy()
c、Reduce:【KeyedStream -> DataStream】,【x:上次计算得出的结果当做本次的参数, y:当前最新的数据】
3、多流转换算子:
a、split:【DataStream ->SplitStream】根据某些特征把一个 DataStream 拆分成两个或者多个DataStream 。
b、select:【SplitStream ->DataStream】从SplitStream中选出某个DataStream
例如:
val splitStream = dataStream
      .split( sensorData => {
        if( sensorData.temperature > 30 ) Seq("high") else Seq("low")
      } )
val highTempStream = splitStream.select("high")
val lowTempStream = splitStream.select("low")
c、connect:【DataStream,DataStream  -> ConnectedStreams】
d、map:【ConnectedStreams -> DataStream】【不需要两个流是相同的数据类型】
例如:
val connectedStreams = stream1.connect(stream2)
val coMapStream = connectedStreams.map(
  warningData => ( warningData._1, warningData._2, "high temperature warning" ),
  lowData => ( lowData.id, "healthy" )
)
e、union:【DataStream1 + DataStream2 -> DataStream】【需要两个流是相同的数据类型】

 

增量聚合:
reduce:数据的输入和输出类型要一样,窗口后的reduce对象只初始化一次。数据到一个就执行一次reduce()f方法(注:两个数以上才会执行reduce()方法,否则数据直接到下游)
aggregateFunction:窗口中第一个数据到了会执行create()和add(),之后每接收一个数据执行一次add(),窗口关闭之后执行getResult()
全量聚合:
apply:数据的输入和输出类型可以不一样。数据都到了(窗口关闭之后)才会执行apply()方法(也就是一个窗口只执行一次apply()方法),在apply()方法中遍历所有数据
增量聚合与全量聚合相同点:都是窗口结束,提交数据到下游

 

二、Flink支持的数据类型
1、基础数据类型:DataStream[Long]
2、java和scala元祖:DataStream[(String, Integer)]
3、scala样例类:class Person(name:String age:Int)
4、java对象
5、Flink对Java和Scala中的一些特殊目的的类型也都是支持的,比如Java的ArrayList HashMap Enum

三、函数
1、富函数
a、富函数,可以获取到运行时上下文,还有一些生命周期函数【open、close】
b、open:一般放一些初始化的操作,比如数据库的连接
class MyMapper() extends RichMapFunction[SensorReading, String]{
  override def map(value: SensorReading): String = {
    "flink"
  }
  override def open(parameters: Configuration): Unit = super.open(parameters)
}


四、Sink
1、如输出到es、kafka、redis、mysql

五、windows-API
1、Window将一个无限的stream拆分成有限大小的”buckets”桶。
2、bucket可能有多个,接收的数据可能同时进入多个桶

start = timestamp-(timestamp-offset+windowSize)%weindowSize   [start, end)
(一)window类型
CountWindow:按照指定的数据条数生成一个Window与时间无关。
TimeWindow:按照时间生成 Window。可以根据窗口实现原理的不同分成三类:滚动窗口(Tumbling Window)、滑动窗口(Sliding Window)和会话窗口(Session Window)
1、滚动窗口(Tumbling Window)
a、特点:时间对齐,窗口长度固定,没有重叠。
b、适用场景:适合做BI统计等(做每个时间段的聚合计算)。

2、滑动窗口(Sliding Window)
a、特点:时间对齐,窗口长度固定,可以有重叠。
b、适用场景:对最近一个时间段内的统计(求某接口最近 5min 的失败率来决定是否要报警)。

2、会话窗口(Session Window)
a、特点:时间无对齐。由一系列事件组合一个指定时间长度的timeout间隙组成,类似web应用的session,也就是一段时间没有接收到新数据就会生成新的窗口。
b、适用场景:对最近一个时间段内的统计(求某接口最近 5min 的失败率来决定是否要报警)。

 

(二)window-API
【DataStream---->WindowStream---->DataStream】
1、窗口的各种操作
val resultStream = dataStream.map(data => (data.id, data.temperature))
        .keyBy(_._1)
//        .window(TumblingEventTimeWindows.of(Time.seconds(15)))  //滚动时间窗口
//        .window(SlidingProcessingTimeWindows.of(Time.seconds(15), Time.seconds(3)))  //滑动时间窗口
//        .window(EventTimeSessionWindows.withGap(Time.seconds(10))) //回话窗口
//简写
        .timeWindow(Time.seconds(15), Time.seconds(3))  //时间滑动窗口
//        .countWindow(10,3)   //计数滑动窗口

2、窗口方法
window function 定义了要对窗口中收集的数据做的计算操作,主要可以分为两类:
【增量聚合函数incremental aggregation functions】
每条数据到来就进行计算,保持一个简单的状态。典型的增量聚合函数有ReduceFunction, AggregateFunction
【全窗口函数full window functions】
先把窗口所有数据收集起来,等到计算的时候会遍历所有数据。ProcessWindowFunction,apply就是一个全窗口函数。

3、其他可选api
【.trigger() 触发器】:定义window什么时候关闭,触发计算并输出结果
【.evitor() 移除器】:定义移除某些数据的逻辑
【.allowedLateness()】:允许处理迟到的数据
【.sideOutputLateData()】:将迟到的数据放入侧输出流
【.getSideOutput()】:获取侧输出流

 

六、时间语义&watermark

(一)、时间语义

Event Time:是事件创建的时间。
Ingestion Time:是数据进入 Flink 的时间。
Processing Time:是每一个执行基于时间操作的算子的本地系统时间,与机器相关,默认的时间属性就是 Processing Time

(二)wartermark

1、保证一个特定的时间后,必须触发window去进行计算,这个特别的机制,就是Watermark。
2、Watermark是用于处理乱序事件的,而正确的处理乱序事件,通常用Watermark机制结合window来实现。
3、数据流中的Watermark用于表示timestamp小于Watermark 的数据,都已经到达了,因此,window的执行也是由Watermark触发的。
4、Watermark 是一种衡量Event Time进展的机制。
5、特点
a、watermark是一条特殊记录,单调递增,wartermark=最大的eventTime-延迟时间当wartermark为某个窗口时间时,该窗口就会被关闭

6、watermark上下游传播方式
a、上游:以广播的方式传递给下游
b、下游:记录map(上游id,wartermark),下游的wartermark以最小的warkermark为准

7、eventTime&wartermark的引入
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
env.getConfig.setAutoWatermarkInterval(500)  //设置插入wartermark的周期,默认为200ms,这里设置为500ms
a、数据有序:.assignAscendingTimestamps(_.timestamp * 1000L)----->eventTime为timestamp
b、乱序数据:eventTime为timestamp,延迟时间为Time.seconds(1)
.assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor[SensorReading](Time.seconds(1)) {
  override def extractTimestamp(element: SensorReading): Long = element.timestamp * 1000L----->eventTime为timestamp
})

 

总结:【.延迟时间(3秒).window.allowedLateness(1分钟).sideOutputLateData.reduce场景】

val dataStream = inputStream
      .map(
        data => {
          val dataArray = data.split(",")
          SensorReading(dataArray(0).trim, dataArray(1).trim.toLong, dataArray(2).trim.toDouble)
        }
      )
//              .assignAscendingTimestamps(_.timestamp * 1000L) //设置eventTime,升序可以设置这个。乱序要设置wartermark,如下:
      .assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor[SensorReading](Time.seconds(1)) {
      override def extractTimestamp(element: SensorReading): Long = element.timestamp * 1000L
    })
//      .assignTimestampsAndWatermarks( new MyAssigner() )
      .map(data => (data.id, data.temperature))
      .keyBy(_._1) //按照二元组的第一个元素分组
//        .process( new MyProcess() )
      .timeWindow(Time.seconds(10), Time.seconds(3))
      .allowedLateness(Time.minutes(1))  //------>允许最大的迟到数据
      .sideOutputLateData(new OutputTag[(String, Double)]("late"))  //--->迟到的数据进入“late”流
      .reduce((result, data) => (data._1, result._2.min(data._2))) // 统计10秒内的最低温度值


数据(eventTime)到达flink,计算出wartermark(wartermark = dataTime - 延迟时间)---->wartermark<windowTime---->数据累计在窗口中(bucket中)---->wartermark=windowTime---->输出一条数据---->windowTime<wartermark<windowTime+allowedLateness+延迟时间,每收到dataTime<windowTime的数据,都会输出一次---->wartermark>windowTime+allowedLateness时,关闭窗口,数据输出到sideOutputLateData

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值