第十六周 Flink极速上手篇-Flink核心API之DataStreamAPI-3
Flink核心API

1 | Flink中提供了4种不同层次的API,每种API在简洁和易表达之间有自己的权衡,适用于不同的场景。目前上面3个会用得比较多。 |
1 | 低级API(Stateful Stream Processing):提供了对时间和状态的细粒度控制,简洁性和易用性较差,主要应用在一些复杂事件处理逻辑上。 |

DataStream API
1 | DataStream API主要分为3块:DataSource、Transformation、DataSink。 |
DataStream API之DataSoure
1 | DataSource是程序的输入数据源,Flink提供了大量内置的DataSource,也支持自定义DataSource,不过目前Flink提供的这些已经足够我们正常使用了。 |

1 | Flink内置:表示Flink中默认自带的。 |

1 | 针对这些常用的DataSouce,基于socket的我们之前已经用过了,下面我们来看一下基于Collection集合的。 |

1 | 接下来在 com.imooc.scala.stream 里面创建一个包:source,将代码放到source包里面 |
scala
1 | package com.imooc.scala.stream.source |
java
1 | package com.imooc.java.stream.source; |
自定义DataSource(作业)
1 | 题目描述: |
多并行度
1 | import org.apache.flink.streaming.api.functions.source.{ParallelSourceFunction, SourceFunction} |
1 | import org.apache.flink.streaming.api.scala._ |
单并行度
1 | import org.apache.flink.streaming.api.functions.source.SourceFunction |
1 | import org.apache.flink.streaming.api.scala._ |
DataStream API之Transformation
1 | transformation是Flink程序的计算算子,负责对数据进行处理,Flink提供了大量的算子,其实Flink中的大部分算子的使用和spark中算子的使用是一样的,下面我们来看一下: |
1 | 算子 解释 |
1 | 这里面的算子的用法其实和spark中对应算子的用法是一致的,这里面的map、flatmap、keyBy、reduce、sum这些算子我们都用过了。 |
1 | 算子 解 释 |
1 | 这里面的算子我们需要分析一下。 |
union
scala
1 | package com.imooc.scala.stream.transformation |
java
1 | package com.imooc.java.stream.transformation; |
connect
1 | connect:只能连接两个流,两个流的数据类型可以不同 |
scala
1 | package com.imooc.java.stream.transformation |

java
1 | package com.imooc.java.stream.transformation; |
split
1 | split:根据规则把一个数据流切分为多个流 |
1 | split需要和select配合使用,选择切分后的流 |
scala
1 | package com.imooc.java.stream.transformation |
java
1 | package com.imooc.java.stream.transformation; |
1 | 目前split切分的流无法进行二次切分,并且split方法已经标记为过时了,官方不推荐使用,现在官方推荐使用side output的方式实现。 |
side output
1 | 下面我来看一下使用side output如何实现流的多次切分 |
scala
1 | package com.imooc.java.stream.transformation |

java
1 | package com.imooc.java.stream.transformation; |
总结
1 | 其实想要实现多级流切分,使用filter算子也是可以实现的,给大家留一个作业,大家可以下去实验一下。 |

1 | union可以连接多个流,最后汇总成一个流,流里面的数据使用相同的计算规则 |

分区相关算子
random(shuffle)
1 | 接下来看一下这几个和分区相关的算子 |
rebalance
1 | rebalance:重新平衡分区(循环分区),我觉得叫循环分区更好理解,它表示对数据集进行再平衡,消除数据倾斜,为每个分区创建相同的负载,其实就是通过循环的方式给下游算子实例的每个分区分配数据,在代码层面体现是调用rebalance()函数 |
1 | public void setup(int numberOfChannels) { |
rescale
1 | rescale:重分区 |
1 | public int selectChannel(SerializationDelegate<StreamRecord<T>> record) { |
1 | 详细的解释在这个类的注释中也是有的 |
1 | * The subset of downstream operations to which the upstream operation sends |
1 | 如果上游操作有2个并发,而下游操作有4个并发,那么上游的1个并发结果循环分配给下游的2个并发操作,上游的另外1个并发结果循环分配给下游的另外2个并发操作。 |
1 | 注意:rescale与rebalance的区别是rebalance会产生全量重分区,而rescale不会。 |
broadcast
1 | broadcast:广播分区,将上游算子实例中的数据输出到下游算子实例的每个分区中,适合用于大数据集Join小数据集的场景,可以提高性能。 |
1 | /** |
custom partition
1 | custom partition:自定义分区,可以按照自定义规则实现 |
总结



1 | 最后使用代码演示一下它们具体的用法 |
scala
1 | package com.imooc.scala.stream.transformation |
1 | package com.imooc.scala.stream.transformation |
1 | custom partition |

1 | broadcast 此时每个数据都有四次输出 |

1 | rescale 四个分区都有输出 |

1 | rebalance 四个分区都有数据输出 |

1 | shuffle 不一定每个分区都有数据输出 |

java
1 | package com.imooc.java.stream.transformation; |
DataStream API之DataSink
1 | DataSink是 输出组件,负责把计算好的数据输出到其它存储介质中 |
1 | Flink内置 Apache Bahir |
1 | 针对sink的这些connector,我们在实际工作中最常用的是kafka、redis |

1 | 针对kafka这个sink组件的使用,我们在后面会统一分析,现在我们来使用一下redis这个sink组件 |
redis
1 | 先到Flink官网,文档,connector,datasteam,redis,添加对应的依赖(一般不是正确的依赖,把名字复制到maven官网,查找) |
scala
1 | 注意:redis sink是在Bahir这个依赖包中,所以在pom.xml中需要添加对应的依赖 |
1 | <dependency> |
1 | package com.imooc.scala.stream.sink |
1 | 注意:针对List数据类型,我们在定义getCommandDescription方法的时候,使用new |
1 | 通过socket传递单词 |


1 | 最终到redis中查看结果 |

java
1 | package com.imooc.java.stream.sink; |
自定义DataSink
1 | 题目描述: |
RichSinkFunction
1 | import java.sql.{Connection, DriverManager, PreparedStatement} |
1 | import org.apache.flink.streaming.api.scala._ |
JDBC
1 | import org.apache.flink.connector.jdbc.JdbcSink |