03 Flink 之Transform转换算子

本文详细介绍了Apache Flink中的关键转换算子,包括map、flatMap、filter、keyBy、rolling aggregation、reduce、split/select、connect/coMap、union等,通过示例展示了如何使用这些算子处理和分析数据流。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Flink 之 Transform转换算子

1. map

  1. 作用: 对输入元素进行映射转换。

  2. 示例:

    import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment}
    import org.apache.flink.api.scala._
    
    object TestMap {
      def main(args: Array[String]): Unit = {
        // 创建执行环境
        val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
        // 创建输入的 DateStream
        val input: DataStream[Int] = env.fromElements[Int](1,2,3,4)
        // 使用 map 对输入进行处理,得到结果
        val output: DataStream[Int] = input.map(data => data + 1)
        // 输出结果
        output.print()  // 2 3 4 5
        // 执行任务
        env.execute()
      }
    }
    

2. flatMap

  1. 作用:map(func) 类似,但是每一个输入可以被映射成 0 或多个输出元素。

  2. 示例:

    import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment}
    import org.apache.flink.api.scala._
    
    object TestFlatMap {
      def main(args: Array[String]): Unit = {
        // 创建运行环境
        val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
        // 创建DS输入
        val input: DataStream[String] = env.fromCollection(List("a b", "c d"))
        // 通过 flatMap 对数据进行切割
        val output: DataStream[String] = input.flatMap(strs => strs.split(" "))
        // 将结果输出
        output.print()  // a b c d
        // 执行任务
        env.execute()
      }
    }
    

3. filter

image-20200530120226361
  1. 作用: 过滤数据。

  2. 示例:

    import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment}
    import org.apache.flink.api.scala._
    
    object TestFilter {
      def main(args: Array[String]): Unit = {
        // 创建运行环境
        val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
        // 创建 DS 输入
        val input: DataStream[String] = env.fromElements("xiaohong","xiaoming","mingming","xiaozhang")
        // 过滤掉不含 "xiao" 的字符串
        val output: DataStream[String] = input.filter(_.contains("xiao"))
        // 输出结果
        output.print()
        // 执行任务
        env.execute()
      }
    }
    

4. keyBy

image-20200530151927115
  1. 作用: DataStream → KeyedStream 逻辑地将一个流拆分成不相交的分区,每个分区包含具有相同 key 的元素,在内部以 hash 的形式实现的。

  2. 示例:

    import org.apache.flink.api.java.tuple.Tuple
    import org.apache.flink.api.scala._
    import org.apache.flink.streaming.api.scala.{DataStream, KeyedStream, StreamExecutionEnvironment}
    
    object TestKeyBy {
      def main(args: Array[String]): Unit = {
        // 创建执行环境
        val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
        // 创建 DS
        val input: DataStream[(Int, String)] = env.fromElements(Tuple2(1,"a"), Tuple2(2,"b"), Tuple2(3,"c"), Tuple2(2,"a"))
        // 根据元组的第一个元素分流
        val output: KeyedStream[(Int, String), Tuple] = input.keyBy(0)
        // 输出结果
        output.print()
        // 执行任务
        env.execute()
      }
    }
    
  3. 注意: 以下类型无法作为 key

    • POJO 类( Java 简单对象) 且 没有实现 hashCode函数。
    • 任意形式的数组类型。

5. 滚动聚合算子(Rolling Aggregation)

  1. 这些算子可以针对 keyedStream 的每一个支流做聚合。
    • sum()
    • min()
    • max()
    • minBy()
    • maxBy()

6. reduce

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

  2. 示例:

    val textPath = "/Users/zgl/Documents/IdeaProjects/FlinkTutorial/src/sensors.txt"
    val input: DataStream[String] = env.readTextFile(textPath)
    val output: DataStream[SensorReading] = input.map(line => {
                                                            val fields = line.split(",")
                                                            SensorReading(fields(0).trim, fields(1).trim.toLong, fields(2).trim.toDouble)
                                                                  })
                                                      .keyBy("id")
                                                      .reduce((x, y) => SensorReading(x.id, x.timestamp+1, y.temperature))
    

7. split 和 select

7.1 split

image-20200601114638488
  1. 作用: DataStream → SplitStream:根据某些特征把一个 DataStream 拆分成两个或者多个 DataStream

7.2 select

image-20200601114802484
  1. 作用: SplitStream→DataStream:从一个 SplitStream 中获取一个或者多个 DataStream

  2. 示例:

    import com.guli.source.SensorReading
    import org.apache.flink.api.scala._
    import org.apache.flink.streaming.api.scala.{DataStream, SplitStream, StreamExecutionEnvironment}
    
    object TestSplit_Select {
      def main(args: Array[String]): Unit = {
        val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    
        val input: DataStream[SensorReading] = env.fromCollection(List(
          SensorReading("sensor_1", 1547718199, 35.80018327300259),
          SensorReading("sensor_6", 1547718201, 15.402984393403084),
          SensorReading("sensor_7", 1547718202, 6.720945201171228),
          SensorReading("sensor_10", 1547718205, 38.101067604893444)
        ))
    
        val splitStream: SplitStream[SensorReading] = input.split( sensorData => if (sensorData.temperature > 30) Seq("high") else Seq("low"))
    
        val highStream: DataStream[SensorReading] = splitStream.select("high")
        val lowStream: DataStream[SensorReading] = splitStream.select("low")
        val allStream: DataStream[SensorReading] = splitStream.select("high", "low")
    
        highStream.print()
        //lowStream.print()
        //allStream.print()
    
        env.execute()
      }
    }
    

8. connect 和 coMap

8.1 connect

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

8.2 coMap 、 coFlatMap

image-20200601120403001
  1. 作用: ConnectedStreams → DataStream:作用于 ConnectedStreams 上,功能与 mapflatMap 一样,对 ConnectedStreams 中的每一个 Stream 分别进行 mapflatMap处理。

  2. 示例:

    val warning = highStream.map( sensorData => (sensorData.id, sensorData.temperature) )
    val connected = warning.connect(lowStream)
    val coMap = connected.map(warningData => (warningData._1, warningData._2, "warning"),
    													lowData => (lowData.id, "healthy") )
    

9. union

image-20200601121320282
  1. ** 作用: ** DataStream → DataStream:对两个或者两个以上的 DataStream 进行 union 操作,产生一个包含所有 DataStream 元素的新 DataStream

  2. 示例:

    //合并以后打印
    val unionStream: DataStream[StartUpLog] = appStoreStream.union(otherStream)
    unionStream.print("union:::")
    

10. connect 和 union 的区别

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值