Flink流处理API——Transform(转换算子)

9 篇文章 0 订阅
8 篇文章 0 订阅

原文链接:https://www.toutiao.com/i6859612664646238724/

本文主要从以下几个方面介绍Flink的流处理API——Transform

一、map

二、flatmap

三、Filter

四、KeyBy

五、滚动聚合算子(Rolling Aggregation)

六、Reduce

七、Split和Select

八、Connect和CoMap

九、Union

数据处理的过程基本可以分为三个阶段分别是,数据从来哪里,做什么业务逻辑,落地到哪里去。

这三部分在Flink中分别被称为Source、Transform和Sink

其中Source可以看这篇文章:Flink流处理API——Source

版本:

scala:2.11.12

Flink:1.7.2

pom.xml依赖部分(log日志的依赖一定要加上,否则当Flink从Kafka0.8中读取数据报Failed to instantiate SLF4J LoggerFactory Reported exception)

    <dependencies>

        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-scala_2.11</artifactId>
            <version>1.7.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-streaming-scala_2.11</artifactId>
            <version>1.7.2</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-clients_2.11</artifactId>
            <version>1.7.2</version>
        </dependency>

      
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.22</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.22</version>
        </dependency>
    </dependencies>

数据源:(Source)部分

package xxx

import org.apache.flink.api.common.functions.FilterFunction
import org.apache.flink.streaming.api.scala._

// 样例类,传感器ID,时间戳,温度
case class SensorReading(id: String, timestamo: Long, temperature: Double){
  override def toString: String = {
    id+":"+ timestamo.toString + "," + temperature
  }
}

object TransformAPIDemo {
  def main(args: Array[String]): Unit = {

    val environment: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment

    val value: DataStream[String] = environment.readTextFile("src\\main\\resources\\sensor.txt")

// 这里Transform操作
    environment.execute()

  }
}

接下来以对value的操作进行说明各个Transform算子的作用

一、map

map是左转换操作,将DataStream[A]的数据转换成DataStream[B]的数据。

Flink流处理API——Transform(转换算子)

 

    // map
    val maped: DataStream[SensorReading] = value.map(line => {
      val fildes: Array[String] = line.split(",")  // 这里的split是scala的split方法
      SensorReading(fildes(0).trim, fildes(1).trim.toLong, fildes(2).trim.toDouble)
    })

二、flatmap

flatmap和map的功能类似,都是将DataStream[A]的数据转换成DataStream[B]的数据。所不用的是,flatmap打散的效果更彻底,会将集合中的数据全部拿出后打算,不保留集合原状。

List("a b", "c d").flatMap(line ⇒ line.split(" "))
结果是 List(a, b, c, d)。 

三、Filter

Flink流处理API——Transform(转换算子)

 

fliter将是DataStream[A]的数据进行过滤,该算子需要传入满足过滤的条件:

// fliterval 
fliter: DataStream[SensorReading] = maped.filter(sensor => {
  sensor.id.endsWith("0")
})

四、KeyBy

Flink流处理API——Transform(转换算子)

 

将DataStream 的数据转换成KeyedStream的数据:

逻辑地将一个流拆分成不相交的分区,每个分区包含具有相同 key 的元素, 在内部以 hash 的形式实现的。

KeyBy是后续一些聚合算子、开窗算子的前提。

五、滚动聚合算子(Rolling Aggregation)

聚合算子可以针对 KeyedStream 的每一个支流做聚合。也就是前面经过KeyBy操作后的数据流。

常用的聚合算子有:

sum()

min()

max()

minBy()

maxBy()

例如,求每个传感器的最低温度如下:

    // kayBy、sum(括号的参数表示按照第几个字段进行分流、聚合等)
    val sumed: DataStream[SensorReading] = maped.keyBy(0).min(2)

需要注意的是,每来一条数据都会计算一次min值(聚合一次),并返回。

经过聚合后,KeyedStream又回到DataStream类型。但是这几个聚合算子往往不能满足实际业务需求,就需要功能更强大的reduce聚合算子。

六、Reduce

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

用reduce同样可以实现每个传感器最低温度

 // keyBy、reduce (DataStream要先经过KeyBy形成KeyedStream后才能调用reduce算子)
    val reduced: DataStream[SensorReading] = maped.keyBy(0).reduce((x, y) => { // x:之前聚合的结果, y:本次数据
      SensorReading(x.id, y.timestamo, x.temperature.min(y.temperature))
    })

七、Split和Select

Flink流处理API——Transform(转换算子)

 

Split算子是将DataStream类型的数转化为SplitStream类型的数据

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

Flink流处理API——Transform(转换算子)

 

Select算子是将SplitStream类型的数据在转化为DataStream类型的数据:

从一个 SplitStream 中获取一个或者多个 DataStream。
Split和Select往往配合使用

   // split, select
 // 在split传入分割条件,设置tag,在select中选择tag 
    val splited: SplitStream[SensorReading] = maped.split(data => {
      if (data.temperature > 30) Seq("High")
      else Seq("Low")
    })
    val highStream: DataStream[SensorReading] = splited.select("High")
    val lowStream: DataStream[SensorReading] = splited.select("Low")
    val allStream: DataStream[SensorReading] = splited.select("High", "Low")

八、Connect和CoMap

Flink流处理API——Transform(转换算子)

 

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

Flink流处理API——Transform(转换算子)

 

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

  // 让highStream2变成元祖类型,而lowStream是SensorReading类型
    val highStream2: DataStream[(String, Double)] = highStream.map(sensor => {
      (sensor.id, sensor.temperature)
    })
    // connect,CoMap (支持不同类型的合并)
    val highAndLowStream: ConnectedStreams[(String,Double), SensorReading] = highStream2.connect(lowStream)
    val coMap: DataStream[Product] = highAndLowStream.map(
      highData => (highData, "high"),
      lowData => (lowData)
    )

coMap中需要对不同的数据流指定不同的操作流程。

九、Union

Flink流处理API——Transform(转换算子)

 

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

 // union
    val highUnionLowStream: DataStream[SensorReading] = highStream.union(lowStream)

Connect 与 Union 区别:

1. Union 之前两个流的类型必须是一样, Connect 可以不一样,在之后的 coMap中再去调整成为一样的。

2. Connect 只能操作两个流, Union 可以操作多个。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值