DataStream API【2】

Transformation数据转换(转换算子)

在Flink中,Transformation(转换)算子就是将一个或多个DataStream转换为新的DataStream,可以将多个转换组合成复杂的数据流(Dataflow)拓扑。

  1. map(func)
    map()算子接收一个函数作为参数,并把这个函数应用于DataStream的每个元素,最后将函数的返回结果作为结果DataStream中对应元素的值,即将DataStream的每个元素转换成新的元素。
    如以下代码所示,对dataStream1应用map()算子,将dataStream1中的每个元素加一并返回一个名为dataStream2的新DataStream:
val dataStream1=senv.fromCollection(List(1,2,3,4,5,6))
val dataStream2=dataStream1.map(x=>x+1)
  1. flatMap(func)
    与map()算子类似,但是每个传入该函数func的DataStream元素会返回0到多个元素,最终会将返回的所有元素合并到一个DataStream。
    例如以下代码将集合List转为dataStream1,然后调用dataStream1的flatMap()算子将dataStream1的每个元素按照空格分割成多个元素,最终合并所有元素到一个新的DataStream。
//创建DataStream
val dataStream1=senv.fromCollection(
    List("hadoop hello scala","flink hello")
)
//调用flatMap()算子进行运算
val dataStream2=dataStream1.flatMap(_.split(" "))
//打印结果到控制台
dataStream2.print()
//触发任务执行,指定作业名称
senv.execute("MyJob")
  1. filter(func)
    通过函数func对源DataStream的每个元素进行过滤,并返回一个新的DataStream。
    例如以下代码,过滤出dataStream1中大于3的所有元素,并输出结果。
val dataStream1=senv.fromCollection(List(1,2,3,4,5,6))
val dataStream2=dataStream1.filter(_>3)
dataStream2.print()

控制台输出结果如下:
1> 4
2> 5
3> 6
4. keyBy()
keyBy()算子主要作用于元素类型是元组或数组的DataStream上。使用该算子可以将DataStream中的元素按照指定的key(指定的字段)进行分组,具有相同key的元素将进入同一个分区中(不进行聚合),并且不改变原来元素的数据结构。例如,根据元素的形状对元素进行分组,相同形状的元素将被分配到一起,可被后续算子统一处理
假设有两个同学zhangsan和lisi,zhangsan的语文和数学成绩分别为98、78,lisi的语文和数学成绩分别为88、79。将数据集的姓名作为key进行keyBy()操作,代码如下:

val dataStream=senv.fromCollection(
    List(("zhangsan",98),("zhangsan",78),("lisi",88),("lisi",79))
)
//使用数字位置指定,按照第一个字段分组
val keyedStream: KeyedStream[(String, Int), Tuple]=dataStream.keyBy(_._1)
keyedStream.print()

控制台输出结果如下:
4> (lisi,88)
4> (lisi,79)
3> (zhangsan,98)
3> (zhangsan,78)
从上述输出结果可以看出,
同一组的元素被同一个线程执行。

keyBy()算子的执行对象是DataStream,执行结果则是KeyedStream。KeyedStream实际上是一种特殊的DataStream,因为其继承了DataStream。KeyedStream用来表示根据指定的key进行分组的数据流。

  1. reduce()
    reduce()算子主要作用于KeyedStream上,对KeyedStream数据流进行滚动聚合,即将当前元素与上一个聚合值进行合并,并且发射出新值。该算子的原理与MapReduce中的Reduce类似,聚合前后的元素类型保持一致。
    reduce()算子始终以滚动的方式将两个元素合并为一个元素,最终将一组元素合并为单个元素。reduce()算子可以用于整个数据集,也可以用于分组的数据集。该算子的执行效率比较高,因为它允许系统使用更有效的执行策略。
    继续对前面两个同学zhangsan和lisi的成绩进行reduce()操作,求出每个同学的总成绩,代码如下:
val reducedDataStream: DataStream[(String, Int)] = keyedStream
  .reduce((t1, t2) => {
//聚合规则:将每一组的第二个字段进行累加,第一个字段保持不变。注意聚合后数据类型与聚合前保持一致(String, Int)
      (t1._1, t1._2 + t2._2)
  })
reducedDataStream.print()
  1. Aggregation
    除了reduce()算子外,其他常用的聚合算子有sum()、max()、min()等,这些聚合算子统称为Aggregation。Aggregation算子作用于KeyedStream上,并且进行滚动聚合。与keyBy()算子类似,可以使用数字或字段名称指定需要聚合的字段。例如以下代码:
keyedStream.sum(0);//对第一个字段进行求和
keyedStream.sum("key");//对字段key进行求和
keyedStream.min(0);
keyedStream.min("key");
keyedStream.max(0);
keyedStream.max("key");
keyedStream.minBy(0);
keyedStream.minBy("key");
keyedStream.maxBy(0);
keyedStream.maxBy("key");

keyBy()算子会将DataStream转换为KeyedStream,而Aggregation算子会将KeyedStream转换为DataStream。

  1. union()
    union()算子用于将两个或多个数据流进行合并,创建一个包含所有数据流所有元素的新流(不会去除重复元素)。如果将一个数据流与它本身合并,在结果流中,每个元素会出现两次。使用union()算子合并数据流。
    union()算子执行过程中,多条数据流中的元素会以先进先出的方式合并,无法保证顺序,每个输入的元素都会被发往下游算子。使用union()算子对两个数据流进行合并,代码如下:
//创建数据流一
val dataStream1 = senv.fromElements(
    (0, 0, 0), (1, 1, 1), (2, 2, 2)
)
//创建数据流二
val dataStream2 = senv.fromElements(
    (3, 3, 3), (4, 4, 4), (5, 5, 5)
)
//合并两个数据流
val unionDataStream=dataStream1.union(dataStream2)
unionDataStream.print()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值