Flink笔记7:Flink流处理API之Transform

1、map与flatMap

在这里插入图片描述

val streamMap = stream.map { x => x * 2 }

flatMap 的函数签名:def flatMap[A,B](as: List[A])(f: A ⇒ List[B]): List[B]
例如: 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)

val streamFlatMap = stream.flatMap{
    x => x.split(" ")
}

2、Filter

在这里插入图片描述

val streamFilter = stream.filter{
    x => x == 1
}

3、KeyBy与滚动聚合算子(Rolling Aggregation)

在这里插入图片描述
DataStream → KeyedStream:KeyBy逻辑地将一个流拆分成不相交的分区,每个分区包含具有相同key 的元素,在内部以hash 的形式实现的。

KeyBy一般结合滚动聚合算子使用。滚动聚合算子(Rolling Aggregation)可以针对KeyedStream 的每一个支流做聚合。常用的滚动聚合算子:

sum()
min()
max()
minBy()
maxBy()

// 分组聚合,输出每个传感器当前最小值
val aggStream = dataStream
  .keyBy("id")    // 根据id进行分组
  .minBy("temperature")

aggStream.print()

min与minBy的区别:
我们看sensor_1的结果,min(“temperature”)的结果只在乎temperature(第三列)的正确性,不管其他列与temperature是否正确对应,如timestamp(第二列)永远为sensor_1第一条数据的timestamp;而minBy(“temperature”)的结果会完整输出整条数据,对应关系也正确。

// 原始数据
sensor_1,1547718199,35.8
sensor_6,1547718201,15.4
sensor_7,1547718202,6.7
sensor_10,1547718205,38.1
sensor_1,1547718206,32
sensor_1,1547718208,36.2
sensor_1,1547718210,29.7
sensor_1,1547718213,30.9
// minBy结果
SensorReading(sensor_1,1547718199,35.8)
SensorReading(sensor_6,1547718201,15.4)
SensorReading(sensor_7,1547718202,6.7)
SensorReading(sensor_10,1547718205,38.1)
SensorReading(sensor_1,1547718206,32.0)
SensorReading(sensor_1,1547718206,32.0)
SensorReading(sensor_1,1547718210,29.7)
SensorReading(sensor_1,1547718210,29.7)
// min结果
SensorReading(sensor_1,1547718199,35.8)
SensorReading(sensor_6,1547718201,15.4)
SensorReading(sensor_7,1547718202,6.7)
SensorReading(sensor_10,1547718205,38.1)
SensorReading(sensor_1,1547718199,32.0)
SensorReading(sensor_1,1547718199,32.0)
SensorReading(sensor_1,1547718199,29.7)
SensorReading(sensor_1,1547718199,29.7)

4、Reduce

KeyedStream → DataStream:一个分组数据流的聚合操作,合并当前的元素和上次聚合的结果,产生一个新的值,返回的流中包含每一次聚合的结果,而不是只返回最后一次聚合的最终结果。

val stream2 = env.readTextFile("YOUR_PATH\\sensor.txt")
  .map( data => {
    val dataArray = data.split(",")
    SensorReading(dataArray(0).trim, dataArray(1).trim.toLong,
      dataArray(2).trim.toDouble)
  })
  .keyBy("id")
  .reduce( new MyReduceFunction )
class MyReduceFunction extends ReduceFunction[SensorReading]{
  //输出当前最小的温度值,以及最近的时间戳
  override def reduce(x: SensorReading, y: SensorReading): SensorReading =
    SensorReading(x.id, y.timestamp, x.temperature.min(y.temperature))
}

注:其中x为流操作上次的结果,y为本次新进入的数据。

也可以直接使用reduce函数

reduce( (x, y) => SensorReading(x.id, y.timestamp, x.temperature.min(y.temperature) )

5、Split 和Select(分流)

在这里插入图片描述

DataStream → SplitStream:根据某些特征把一个DataStream 拆分成两个或者多个DataStream。

在这里插入图片描述

SplitStream→DataStream:从一个SplitStream 中获取一个或者多个DataStream。

需求:传感器数据按照温度高低(以30 度为界),拆分成两个流。

val splitStream = dataStream
      .split( data => {
        if( data.temperature > 30.0 ) Seq("high") else Seq("low")
      } )
val highTempStream = splitStream.select("high")
val lowTempStream = splitStream.select("low")
val allTempStream = splitStream.select("high", "low")

6、Connect 和CoMap(合流)

在这里插入图片描述

DataStream,DataStream → ConnectedStreams:连接两个保持他们类型的数据流,两个数据流被Connect之后,只是被放在了一个同一个流中,内部依然保持各自的数据和形式不发生任何变化,两个流相互独立。

在这里插入图片描述

ConnectedStreams → DataStream:作用于ConnectedStreams 上,功能与map和flatMap一样,对ConnectedStreams 中的每一个Stream 分别进行map 和flatMap处理。

    // 合流,connect
    val warningStream = highTempStream.map( data => (data.id, data.temperature) )
    val connectedStreams = warningStream.connect(lowTempStream)

    // 用coMap对数据进行分别处理
    val coMapResultStream: DataStream[Any] = connectedStreams
      .map(
        waringData => (waringData._1, waringData._2, "warning") ,
        lowTempData => (lowTempData.id, "healthy")
      )

7、Union

图Union

DataStream → DataStream:对两个或者两个以上的DataStream 进行union 操作,产生一个包含所有DataStream 元素的新DataStream。

//合并以后打印
val unionStream = highTempStream.union(lowTempStream, allTempStream)
unionStream.print()

Connect 与Union 区别:

  1. Union 之前两个流的类型必须是一样,Connect 可以不一样,在之后的coMap 中再去调整成为一样的。
  2. Connect 只能操作两个流,Union 可以操作多个。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值