描述了基本 Operators 的 Transformations,应用这些转换后如何进行 physical partitioning(物理分区),以及对Flink算子链的深入了解。
DataStream Transformations
Physical partitioning
Transformation | Description |
---|---|
Custom partitioning DataStream → DataStream CustomPartitionerWrapper< |
使用自定义的 partitioner 为每一条 record 选择下一个 task dataStream.partitionCustom(partitioner, "someKey"); dataStream.partitionCustom(partitioner, 0); |
Random partitioning DataStream → DataStream ShufflePartitioner< |
按随机均匀划分元素 dataStream.shuffle(); |
Rebalancing (Round-robin partitioning) DataStream → DataStream RebalancePartitioner< |
分区循环划分元素,为每个下游创建相等的负载。对于存在数据倾斜的性能优化非常有用。 dataStream.rebalance(); |
Rescaling DataStream → DataStream RescalePartitioner< |
将元素循环(round robin)分配到下游 operator 的子集。如果你的 pipeline 是一下的情况,那么这种方式会非常有用。 例如,将并行数据源的每个实例的数据传输到的下游多个算子(operators)一个子集以分配负载。但不希望 full rebalance,则这非常有用。 如果合理配置 TaskManager 的 slot数量,则数据传输只需要本地传输,而不需要通过网络传输数据。 上游 operators 向的下游 operators 发送 record 取决于上游 operators 和下游 operators 的并行度。 例如,如果上游 operator 的并行度为2,而下游 operator 的并行度为6,则一个上游 operator 将 record 分配给三个下游 operator,而另一个上游 operator 将 record 分配给其他三个下游 operator。相反,如果下游 operator 的并行度为2,而上游 operator 的并行度为6,则三个上游 operator 将分配给一个下游 operator,而其他三个上游 operator 将分配给另一个下游 operator。 如果上下游算子的并行度不是彼此的倍数,则一个或多个下游 operator 将具有来自上游 operator 的不同数量的输入。 如下图: dataStream.rescale(); |
Broadcasting DataStream → DataStream BroadcastPartitioner< |
广播数据到下游的每个partition。 dataStream.broadcast(); |
Local Forward DataStream → DataStream ForwardPartitioner< |
数据传输到本地的下游算子。 dataStream.forward(); |
GlobalPartitioner DataStream → DataStream GlobalPartitioner< |
数据传输到下游子任务id为0的task中。 dataStream.forward(); |
Key Groups DataStream → DataStream KeyGroupStreamPartitioner< |
相同key的值会传输到同一个下游。类似于Rescaling,但是不用再api中指定,再使用keyBy时会自动指定此方法。 dataStream.keyBy(); |
Task chaining 和 资源组
链接两个 Transformations 意味着可以将它们共同放在在同一个线程中执行以获得更好的性能。
默认情况下,Flink会尽可能链接两个算子(例如,两个 Map Transformations)。如果需要,可以使用API对 Task chaining 进行细粒度控制:
在 Flink 中,一个 slot 就是一个资源组。如果需要的话,你可以通过使用api把上下游算子隔离在不同的 slot 中运行。