PyFlink 物理分区(Physical Partitioning)

Flink 也提供了在转换后精确控制流分区的底层控制(如果需要的话),主要通过以下函数:

  • shuffle() - 随机重新分区流
  • global() - 将所有数据发送到下游算子的第一个实例
  • broadcast() - 向下游的每个并行实例广播流
  • forward() - 在可能的情况下保留分区
  • partitionCustom() - 通过用户定义的 Partitioner 进行自定义分区

自定义分区(Custom Partitioning)

DataStream → DataStream
使用用户定义的Partitioner为每个元素选择目标任务

自定义分区允许用户实现自定义的分区逻辑,即控制每个元素发送到哪个下游任务。

要实现自定义分区,需要创建一个实现 Partitioner 接口的类:

data_stream = env.from_collection(collection=[(2, 'a'), (2, 'a'), (3, 'b')])
data_stream.partition_custom(lambda key, num_partition: key % partition, lambda x: x[0])

随机分区(Random Partitioning)

DataStream → DataStream

根据均匀分布随机将元素分区

随机分区可以通过 DataStream 的 shuffle() 方法应用:

data_stream.shuffle()

这会随机将 stream 的元素派发到下游运算符的所有分区上,达到重新均衡分区的效果。

随机分区的特点是:

  • 将元素均匀随机分布到下游所有分区
  • 打破上游的分区与键的相关性
  • 有利于并行度弹性调整

随机分区适用于数据负载失衡的情况,或者上游分区与业务关系不大时,可以随机打散分区。它有利于更好地平衡下游任务的负载。

但随机分区也有消耗,应该在需要时选择使用。

重新缩放(Rescaling)

DataStream → DataStream

以轮询的方式将元素分区到下游运算符的一个子集中。这在一些场景下比较有用,例如您想从每个上游源并行实例扇出到几个下游 mapper 的子集来分配负载,但又不想引入 rebalance() 带来的完全重新均衡。这样可以只需要本地数据传输,而不用通过网络传输数据,这取决于其他配置值如 TaskManager 的 slot 数。

上游操作发送元素到下游操作的子集,取决于上下游运算符的并行度。例如,如果上游运算符并行度为2,下游运算符并行度为6,则一个上游实例会将元素分发到3个下游实例,另一个上游实例分发到其余3个下游实例。如果下游运算符并行度为2,而上游运算符为6,则有3个上游实例分发到一个下游实例,另3个上游实例分发到另一个下游实例。

如果上下游运算符的并行度不是彼此的整数倍,则会有一个或几个下游实例输入数目与其他实例不同。

重新缩放适用于上下游operator并行度不匹配、需要局部调整的场景。它提供了一个介于全局rebalance和forward之间的粒度分区控制。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6C5JKzZQ-1693127699418)(https://files.mdnice.com/user/3948/20094a0a-53a1-4c4f-9733-c90d8657fd19.svg)]

data_stream.rescale()

广播(Broadcasting)

DataStream → DataStream

将元素广播到每一个分区

广播可以通过 DataStream 的 broadcast() 方法来应用:

data_stream.broadcast()

这会将 stream 的每一个元素,广播到下游运算符的所有并行实例上。

广播的特点是:

  • 每个元素会复制到下游所有分区
  • 可以将数据分发到下游所有的并行任务实例
  • 有利于某些需要全局数据的状态计算

广播一般适用于下游任务需要访问全局信息的场景,比如字典表、配置表等需要广播到所有下游实例的小规模数据集。

但广播也存在数据复制的消耗,不能滥用,应该在需要时选择使用。

详细资料请关注微信公众号
PyFlink 物理分区(Physical Partitioning)_第1张图片

你可能感兴趣的:(PyFlink,python,flink,数据仓库,大数据,etl工程师,etl,数据库架构)