0
点赞
收藏
分享

微信扫一扫

Flink用法介绍

自定义source

只需要传入一个SourceFunction即可

val stream4 = env.addSource( new MySensorSource() )

举例说明:随机生成传感器数据

Flink用法介绍_数据

无非就是通过生成随机数据的方式组装成传感器数据而已

Flink用法介绍_ide_02

Transform

  • 转换算子

Flink用法介绍_flink_03

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

  • flatMap

a、
flatMap(List(1,2,3))(i -> List(i,i)) 结果是 List(1,1,2,2,3,3)

b、
List("a b","c d").flatMap(line -> line.split(" ")) 结果是List(a,b,c,c)

代码:

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

  • Filter

Flink用法介绍_ide_04

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

  • KeyBy

Flink用法介绍_flink_05

DataStream、KeyedStream 逻辑地将一个流拆分成不相交的分区 

每个分区包含相同key的元素 在内部以hash的形式实现

代码:

val aggStream = dataStream.keyBy("id")

  • 聚合滚动算子(Rolling Aggregation)

针对keyedStream的每个支流做聚合

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

  • Reduce

​源码​

https://gitee.com/pingfanrenbiji/Flink-UserBehaviorAnalysis/blob/master/FlinkTutorial/src/main/scala/com/xdl/apitest/TransformTest.scala

KeyedStream、DataStream 一个分组数据流的聚合操作

合并当前的元素和上次聚合的结果 产生一个新的值

返回的流中包含每一次聚合的结果

而不是只返回最后一次聚合的最终结果

Flink用法介绍_flink_06Flink用法介绍_数据_07stream splitFlink用法介绍_flink_08stream select

  • ConnectedStreams

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

Flink用法介绍_ide_09

  • CoMap,CoFlatMap

作用于ConnectedStream上功能与map和flatMap一样  
对ConnectedStreams中的每一个stream分别进行map和flatMap处理

Flink用法介绍_flink_10

  • Union

对两个或两个以上的DataStream进行union操作 产生一个包含所有DataStram元素的新的DataStream

​connect和union区别​

1、union之前两个流的类型必须一样 connect可以不一样 在之后的coMap中再调整成一样的

2、Connect只能操作两个流 Union可以操作多个

支持的数据类型

Flink流应用程序处理的是以数据对象表示事件流 

数据对象需要被序列化和反序列化

以便通过网络传送它们或从状态后端、检查点和保存点读取它们

Flink使用类型信息的概念来表示数据类型 

并为每个数据类型生成特定的序列化器、反序列化器和比较器

Flink具有类型提取系统 该系统分析函数的输入和返回类型 

以自动获取类型信息 从而获取序列化和反序列化器

lamdba 函数或泛型类型 需要显示的提供类型信息 才能使得应用程序正常工作或提高性能

基础数据类型

Flink支持Java和Scala中所常见的数据类型

  • Long

val numbers: DataStream[Long] = env.fromElements(1L, 2L, 3L, 4L)

numbers.map( n => n + 1 )

  • 元组

val persons: DataStream[(String, Integer)] = env.fromElements(
("Adam", 17),
("Sarah", 23) )

persons.filter(p => p._2 > 18)

  • 样例类

case class Person(name: String, age: Int)

val persons: DataStream[Person] = env.fromElements(
Person("Adam", 17),
Person("Sarah", 23) )

persons.filter(p => p.age > 18)

  • 简单类

public class Person {
public String name;
public int age;

public Person() {}

public Person(String name, int age) {
this.name = name;
this.age = age;
}
}

DataStream<Person> persons = env.fromElements(
new Person("Alex", 42),
new Person("Wendy", 23));

  • Flink 对 Java 和 Scala(ArrayList,HashMap,Enum等)也支持

实现UDF函数-更细粒度的控制流

函数类(Function classes)

Flink暴露了所有udf函数的接口(实现方式为接口或抽象类)

例如:

MapFunction、FilterFunction、ProcessFunction

  • 实现FilterFunction接口

class FilterFilter extends FilterFunction[String] {
override def filter(value: String): Boolean = {
value.contains("flink")
}
}

val flinkTweets = tweets.filter(new FlinkFilter)

  • 将函数实现成匿名类

val flinkTweets = tweets.filter(
new RichFilterFunction[String] {
override def filter(value: String): Boolean = {
value.contains("flink")
}
}
)

  • 字符串作为参数传进去

val tweets: DataStream[String] = ...

val flinkTweets = tweets.filter(new KeywordFilter("flink"))

class KeywordFilter(keyWord: String) extends FilterFunction[String] {
override def filter(value: String): Boolean = {
value.contains(keyWord)
}
}

匿名函数(Lamdba Functions)

val tweets: DataStream[String] = ...

val flinkTweets = tweets.filter(_.contains("flink"))

// _ .id 代表 data => data.id

dataStream.filter( _.id.statWith("sensor_1")).print

副函数

函数类接口 所有的Flink函数类都有Rich版本

与常规函数区别:

可以获取运行时上下文
并拥有一些生命周期方法
可以实现更加复杂的功能

a、 RichMapFunction

b、 RichFlatMapFunction

c、 RichFilterFunction

生命周期:

a、open() 是 rich fuction初始化方法

当一个算子例如map或filter被调用之前 open会被调用

b、close方法 是生命周期中的最后一个调用方法 做一些清理工作

c、getRuntimeContext方法 提供了函数的RuntimeContext的一些信息

例如函数的执行并行度、任务的名字以及state状态

  • 代码

class MyFlatMap extends RichFlatMapFunction[Int, (Int, Int)] {
var subTaskIndex = 0

override def open(configuration: Configuration): Unit = {
subTaskIndex = getRuntimeContext.getIndexOfThisSubtask
// 以下可以做一些初始化工作 , 例如建立一个和 HDFS 的连接
}

override def flatMap(in: Int, out: Collector[(Int, Int)]): Unit = {
if (in % 2 == subTaskIndex) {
out.collect((subTaskIndex, in))
}
}
override def close(): Unit = {
// 以下做一些清理工作,例如断开和 HDFS 的连接。
}
}


举报

相关推荐

0 条评论