Flink核心API之DataStream

DataStream API主要分为3块:DataSource、Transformation、DataSink

  • DataSource是程序的输入数据源。
  • Transformation是具体的操作,它对一个或多个输入数据源进行计算处理,例如map、flatMap和filter 等操作。
  • DataSink是程序的输出,它可以把Transformation处理之后的数据输出到指定的存储介质中。

一、常见的DataStream API之Transformation

  • map 输入一个元素进行处理,返回一个元素
  • flatMap 输入一个元素进行处理,可以返回多个元素
  • filter 对数据进行过滤,符合条件的数据会被留下
  • keyBy 根据key分组,相同key的数据会进入同一个分区
  • reduce 对当前元素和上一次的结果进行聚合操作
  • aggregations sum(),min(),max()等
  • union 合并多个流,多个流的数据类型必须一致
  • connect 只能连接两个流,两个流的数据类型可以不同
  • split 根据规则把一个数据流切分为多个流
  • shuffle 随机分区
  • rebalance 对数据集进行再平衡,重分区,消除数据倾斜
  • rescale 重分区
  • partitionCustom 自定义分区

1.1、union 示例

代码:

  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment

    import org.apache.flink.api.scala._
    val text1 = env.fromCollection(Array(1, 2, 3, 4, 5))
    val text2 = env.fromCollection(Array(6, 7, 8, 9, 10))

    val unionStream = text1.union(text2)
    unionStream.print().setParallelism(1)
    env.execute("StreamUnionScala")
  }

结果:

 

1.2、connect:只能连接两个流,两个流的数据类型可以不同

两个流被connect之后,只是被放到了同一个流中,它们内部依然保持各自的数据和形式不发生任何变 化,两个流相互独立。 connect方法会返回connectedStream,在connectedStream中需要使用CoMap、CoFlatMap这种函 数,类似于map和flatmap        


    val text1 = env.fromElements("user:libaowen,age:18")

    val text2 = env.fromElements("user:jack_age:20")

    val connectionStream = text1.connect(text2)
    connectionStream.map(new CoMapFunction[String, String, String] {
      override def map1(value: String): String = {
        value.replace(",", "-")
      }
      override def map2(value: String): String = {
        value.replace("_ ", "-")
      }
    }).print().setParallelism(1)

结果:

1.3、split和side output

split切分的流无法进行二次切分,并且split方法已经标记为过时了,官方不推荐使用,现在官方推荐 使用side output的方式实现。

  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    val text = env.fromCollection(Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
    //按照数据的奇偶性对数据进行分流
    //首先定义两个sideoutput来准备保存切分出来的数据
    val outputTag1 = new OutputTag[Int]("even") {} //保存偶数
    val outputTag2 = new OutputTag[Int]("odd") {} //保存奇数

    val subOutputStream = text.process(new ProcessFunction[Int, Int] {
      override def processElement(value: Int, ctx: ProcessFunction[Int, Int]#Context, collector: Collector[Int]): Unit = {

        if (value <= 5) {
          ctx.output(outputTag1, value)
        } else {
          ctx.output(outputTag2, value)
        }
      }
    })
    val lowStream = subOutputStream.getSideOutput(outputTag1)
    //获取大于5的数据流
    val highStream = subOutputStream.getSideOutput(outputTag2)
    lowStream.print().setParallelism(1)
    highStream.print().setParallelism(1)
    env.execute("StreamUnionScala")
  }


结果:

 

1.4、random、rebalance、rescale、broadcast

  • random  随机分区,它表示将上游数据随机分发到下游算子实例的每个分区中,在代码层面体现是调用 shuffle()函数
  • rebalance:重新平衡分区(循环分区),我觉得叫循环分区更好理解,它表示对数据集进行再平衡,消除 数据倾斜,为每个分区创建相同的负载,其实就是通过循环的方式给下游算子实例的每个分区分配数据, 在代码层面体现是调用rebalance()函数
  • rescale重分区 
  • broadcast:广播分区,将上游算子实例中的数据输出到下游算子实例的每个分区中,适合用于大数据集

rescale与rebalance的区别是rebalance会产生全量重分区,而rescale不会。

        

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值