Flink中的流数据分区主要用于并行处理。通过将数据划分为多个分区,可以在多个TaskManager上并行执行一个Dataflow,从而提高吞吐量和缩短延迟。
Flink中的流数据分区主要通过以下方式实现:
- 通过调用.keyBy()方法使用关键字字段进行分区。具有相同key的数据会被分到同一个分区。
- 自定义Partition类,实现Partition类的Partition()方法,返回数据分区号。
- 调用.shuffle()方法进行随机分区。
- 广播流使用.broadcast()方法,会将数据广播到所有分区。
下面通过例子来说明流数据分区的几种方式:
按key分区:
DataStream<String> stream = env.socketTextStream("localhost", 9999);
// 根据第一个空格前的字段作为key进行分区
DataStream<String> partitionedStream = stream.keyBy(x -> x.split(" ")[0]);
自定义Partition:
DataStream<String> stream = env.socketTextStream("localhost", 9999);
// 自定义字符串首字符长度为1-5的分为Partition 0,6-10的分为Partition 1
stream.partitionCustom(new Partitioner<String>() {
public int partition(String key, int numPartitions) {
if (key.length() >= 1 && key.length() <= 5) {
return 0;
} else {
return 1;
}
}
}, 2); // 设置2个分区
随机分区:
DataStream<String> stream = env.socketTextStream("localhost", 9999);
// 随机分区成2个分区
DataStream<String> partitionedStream = stream.shuffle().rebalance();
广播流:
DataStream<String> stream = env.socketTextStream("localhost", 9999);
// 广播流到所有分区
DataStream<String> broadcastedStream = stream.broadcast();
.keyBy()、自定义Partition、.shuffle()和.broadcast()是Flink中进行流数据分区的四种主要方式。