翻译原文- Application Development DataStream API Operators
概览
操作符将一个或多个DataStream转换为新的DataStream。程序可以将多种转换组合成复杂的数据流拓扑。
本节对基本转换,应用这些转换后的有效物理分区进行描述以及对Flink操作符链的见解。
DataStream转换
原文DataStream Transformations。
Java代码
转换 | 描述 |
---|---|
Map DataStream → DataStream |
取一个元素并产生一个元素。一个映射函数的例子,将输入流的值加倍:![]() |
FlatMap DataStream → DataStream |
取一个元素并产生零个,一个或多个元素。flatmap函数可将句子拆分为单词:。![]() |
Filter DataStream → DataStream |
为每个元素执行一个布尔函数,函数返回true时保留元素。过滤出零值的filter例子:![]() |
KeyBy DataStream → KeyedStream |
从逻辑上将流划分为不相交的分区。所有具有相同键的记录都分配给相同的分区。在内部,keyBy()是通过哈希分区实现的。有多种指定keys的方法。 此转换返回一个KeyedStream,除其他事项外,还需要使用keyed state。 ![]() 注意:在以下情况下,类型不能为键: 1. 类型是POJO类型,但不覆盖hashCode()方法,而是依赖于Object.hashCode()的默认实现。 2. 它是任何类型的数组。 |
Reduce KeyedStream → DataStream |
在keyed数据流上进行“滚动” reduce。将当前元素与最后一个reduce的value合并,并发出新值。 一个创建局部求和流的reduce函数例子: ![]() |
Aggregations KeyedStream → DataStream |
在一个keyed数据流上滚动聚合。min和minBy之间的区别在于min返回最小值,而minBy返回在此字段中具有最小值的元素(max和maxBy相同)。 ![]() |
Window KeyedStream → WindowedStream |
可以在已经分区的KeyedStreams上定义Windows。Windows根据某些特征(例如,最近5秒钟内到达的数据)将每个键中的数据分组。有关Windows的完整说明,请参见Windows。 ![]() |
WindowAll DataStream → AllWindowedStream |
Windows可以在常规DataStreams上定义。Windows根据某些特征(例如,最近5秒钟内到达的数据)将所有流事件分组。有关Windows的完整说明,请参见Windows。 警告:在许多情况下,这是非并行转换。所有记录将被收集在windowAll操作符的一个任务中。 ![]() |
Window Apply WindowedStream → DataStream AllWindowedStream → DataStream |
将一般函数应用于整个窗口。以下是一个手动对窗口元素求和的函数。 注意:如果使用windowAll转换,则需要改用AllWindowFunction。 ![]() |
Window Reduce WindowedStream → DataStream |
将reduce函数应用于窗口,并返回reduced后的值。 ![]() |
Aggregations on windows WindowedStream → DataStream |
聚合窗口的内容。min和minBy之间的区别在于min返回最小值,而minBy返回在此字段中具有最小值的元素(与max和maxBy相同)。 ![]() |
Union DataStream* → DataStream |
两个或多个数据流的并集,以创建一个包含所有流中的所有元素的新流。注意:如果将数据流与其自身合并,则在结果流中每个元素将获得两次。 ![]() |
Window Join DataStream,DataStream → DataStream |
在给定键和一个共同窗口上连接两个数据流。 ![]() |
Interval Join KeyedStream,KeyedStream → DataStream |
在给定的时间间隔上,使用一个共同的key将两个keyed流的两个元素e1和e2连接起来,从而使e1.timestamp + lowerBound <= e2.timestamp <= e1.timestamp + upperBound ![]() |
Window CoGroup DataStream,DataStream → DataStream |
在给定的键和一个共同窗口上将两个数据流组合在一起。![]() |
Connect DataStream,DataStream → ConnectedStreams |
“连接”两个保留其类型的数据流。连接允许两个流之间共享状态。 ![]() |
CoMap, CoFlatMap ConnectedStreams → DataStream |
在连接的数据流上的map和flatMap二者是相似的。(译者:ConnectedStreams转换成一个普通流) ![]() |
Iterate DataStream → IterativeStream → DataStream |
通过将一个操作符的输出重定向到某个先前的操作符,在流中创建“反馈”循环。这对于定义不断更新模型的算法特别有用。以下代码从流开始,并连续应用迭代主体。大于0的元素将被发送回反馈通道,其余元素将被转发到下游。 ![]() |
在元组的数据流上可以进行以下转换:
Java代码
转换 | 描述 |
---|---|
Project DataStream → DataStream |
从元组中选择字段的子集 ![]() |
物理分区
在转换后Flink还通过以下函数在确切的流分区上进行了低级别控制(如果需要)。
Java代码
转换 | 描述 |
---|---|
Custom partitioning DataStream → DataStream |
使用用户定义的分区器为每个元素选择目标任务。 ![]() |
Random partitioning DataStream → DataStream |
根据均匀分布对元素进行随机划分。 ![]() |
Rebalancing (Round-robin partitioning) DataStream → DataStream |
分区元素轮循,从而为每个分区创建相等的负载。在存在数据偏斜的情况下对性能优化很有用。![]() |
Rescaling DataStream → DataStream |
将元素轮询地分配到下游操作符的子集。如果您希望拥有pipelines时这很有用,例如,从一个source的每个并行实例散开到几个mappers的子集以分配负载,但又不希望像rebalance()引起全部重新平衡。这仅需要本地数据传输,而不需要通过网络传输数据,这取决于其他配置值,例如TaskManager的slots数。 上游操作发送元素到的下游操作的子集取决于上游操作和下游操作两者的并行度。例如,如果上游操作具有并行度2,而下游操作具有并行度6,则一个上游操作将元素分配给三个下游操作,而另一个上游操作将分配给其他三个下游操作。另一方面,如果上游操作具有并行性6,而下游操作具有并行性2,则3个上游操作将分配给1个下游操作,而另外3个上游操作将分配给其它1个下游操作。 如果不同的并行度不是彼此的倍数,则一个或几个下游操作将具有与上游操作不同的输入数量。 请参见此图,以查看上面示例中的连接模式: ![]() ![]() |
Broadcasting DataStream → DataStream |
将元素广播到每个分区。 ![]() |
任务链和资源组
Java代码
链接两个后续的转换意味着将它们共同定位在同一线程内以获得更好的性能。如果可能的话,默认情况下Flink会链接操作符(例如,两个后续的映射转换)。如果需要,API可以对链接进行细粒度的控制:
如果要在整个作业中禁用链接,请使用StreamExecutionEnvironment.disableOperatorChaining()。为了获得更精细的控制,可以使用以下函数。请注意,这些函数只能在DataStream转换后使用,因为它们引用的到先前的转换。例如,您可以使用someStream.map(...).startNewChain(),但不能使用someStream.startNewChain()。
一个资源组是Flink中的一个slot,请参阅 slots。如果需要,您可以手动将操作符隔离在不同的slots中。
转换 | 描述 |
---|---|
Start new chain | 从此操作符开始,开始新的链。下面这两个mappers将被链接,并且filter将不会链接到第一个mapper。 ![]() |
Disable chaining | 不链接map操作符 ![]() |
Set slot sharing group | 设置操作符的slot共享组。Flink会将具有相同slot共享组的操作放入同一slot,同时将没有slot共享组的操作保留在其他slot中。这可以用来隔离slot。如果所有输入操作都在同一slot共享组中,则slot共享组将从输入操作继承。默认slot共享组的名称为“ default”,可以通过调用slotSharingGroup(“ default”)将操作显式放入该组中。 ![]() |