Flink中KeyBy、分区、分组的正确理解

news/2024/11/25 4:45:23/

1.Flink中的KeyBy

在Flink中,KeyBy作为我们常用的一个聚合类型算子,它可以按照相同的Key对数据进行重新分区,分区之后分配到对应的子任务当中去。
源码解析
keyBy 得到的结果将不再是 DataStream,而是会将 DataStream 转换为 KeyedStream(键控流),KeyedStream 可以认为是“分区流”或者“键控流”,它是对 DataStream 按照 key 的一个逻辑分区。
所以泛型有两个类型:除去当前流中的元素类型外,还需要指定 key 的类型。
在这里插入图片描述
KeyBy是如何实现分区的呢

Flink中的KeyBy底层其实就是通过Hash实现的,通过对Key的值进行Hash,再做一次murmurHash,取模运算。
再通过Job的并行度,就能获取每个Key应该分配到那个子任务中了。

在这里插入图片描述

2.分组和分区在Flink中的区别

分区:分区(Partitioning)是将数据流划分为多个子集,这些子集可以在不同的任务实例上进行处理,以实现数据的并行处理。
数据具体去往哪个分区,是通过指定的 key 值先进行一次 hash 再进行一次 murmurHash,通过上述计算得到的值再与并行度进行相应的计算得到。
分组:分组(Grouping)是将具有相同键值的数据元素归类到一起,以便进行后续操作(如聚合、窗口计算等)。
key值相同的数据将进入同一个分组中。
注意:数据如果具有相同的key将一定去往同一个分组和分区,但是同一分区中的数据不一定属于同一组。

3.代码示例

package com.flink.DataStream.Aggregation;import org.apache.flink.api.common.RuntimeExecutionMode;
import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.common.typeinfo.Types;
import org.apache.flink.api.java.functions.KeySelector;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.util.Collector;public class FlinkKeyByDemo {public static void main(String[] args) throws Exception {//TODO 创建Flink上下文执行环境StreamExecutionEnvironment streamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment();//设置并行度为1streamExecutionEnvironment.setParallelism(1);//设置执行模式为批处理streamExecutionEnvironment.setRuntimeMode(RuntimeExecutionMode.BATCH);//TODO source 从集合中创建数据源DataStreamSource<String> dataStreamSource = streamExecutionEnvironment.fromElements("hello word", "hello flink");//TODO 方式一 匿名实现类SingleOutputStreamOperator<Tuple2<String, Integer>> outputStreamOperator1 = dataStreamSource.flatMap(new FlatMapFunction<String, String>() {@Overridepublic void flatMap(String s, Collector<String> collector) throws Exception {String[] s1 = s.split(" ");for (String word : s1) {collector.collect(word);}}}).map(new MapFunction<String, Tuple2<String, Integer>>() {@Overridepublic Tuple2<String, Integer> map(String s) throws Exception {Tuple2<String, Integer> aa = Tuple2.of(s, 1);return aa;}})/*** keyBy 得到的结果将不再是 DataStream,而是会将 DataStream 转换为 KeyedStream(键控流)* KeyedStream 可以认为是“分区流”或者“键控流”,它是对 DataStream 按照 key 的一个逻辑分区* 所以泛型有两个类型:除去当前流中的元素类型外,还需要指定 key 的类型。* *//*** 分组和分区在Flink 中具有不同的含义和作用:* 分区:分区(Partitioning)是将数据流划分为多个子集,这些子集可以在不同的任务实例上进行处理,以实现数据的并行处理。*      数据具体去往哪个分区,是通过指定的 key 值先进行一次 hash 再进行一次 murmurHash,通过上述计算得到的值再与并行度进行相应的计算得到。* 分组:分组(Grouping)是将具有相同键值的数据元素归类到一起,以便进行后续操作 (如聚合、窗口计算等)。*      key 值相同的数据将进入同一个分组中。* 注意:数据如果具有相同的key将一定去往同一个分组和分区,但是同一分区中的数据不一定属于同一组。* */.keyBy(new KeySelector<Tuple2<String, Integer>, String>() {@Overridepublic String getKey(Tuple2<String, Integer> stringIntegerTuple2) throws Exception {return stringIntegerTuple2.f0;}}).sum(1);//TODO 方式二 Lamda表达式实现SingleOutputStreamOperator<Tuple2<String, Integer>> outputStreamOperator2 = dataStreamSource.flatMap((String s, Collector<String> collector) -> {String[] s1 = s.split(" ");for (String word : s1) {collector.collect(word);}}).returns(Types.STRING).map((String word) -> {return Tuple2.of(word, 1);})//Java中lamda表达式存在类型擦除.returns(Types.TUPLE(Types.STRING, Types.INT)).keyBy((Tuple2<String, Integer> s) -> {return s.f0;}).sum(1);//TODO sinkoutputStreamOperator1.print("方式一");outputStreamOperator2.print("方式二");//TODO 执行streamExecutionEnvironment.execute("Flink KeyBy Demo");}
}

http://www.ppmy.cn/news/1155393.html

相关文章

qemu 运行 linux

文章目录 qemu 运行 linuxlinux 内核版本生成配置文件编译设备树编译内核报错与解决运行 linux附录脚本参考 qemu 运行 linux linux 内核版本 linux-6.5.7linux 内核下载地址 https://www.kernel.org/可以在浏览器中点击下载&#xff0c;也可以使用命令行下载 wget https:/…

华为云云耀云服务器L实例评测|企业项目最佳实践之建议与总结(十二)

华为云云耀云服务器L实例评测&#xff5c;企业项目最佳实践系列&#xff1a; 华为云云耀云服务器L实例评测&#xff5c;企业项目最佳实践之云服务器介绍(一) 华为云云耀云服务器L实例评测&#xff5c;企业项目最佳实践之华为云介绍(二) 华为云云耀云服务器L实例评测&#xff5…

23面向对象案例1

目录 1、计算连续表达式的一个过程 2、优化后的代码 为什么不能return resultn&#xff1f; 3、用面向对象的方法可以解决冗余的问题&#xff0c;但是还是不能解决result的值可以被随意修改的问题 4、解决不能被随意修改的问题&#xff0c;可以将类属性改成私有变量吗&…

QTableWidget 表格增删数据

QTableWidgetQTableWidgetQTableWidget部分使用方法&#xff0c;如在表格中插入或删除一行数据以及清空表格数据等。在添加数据时&#xff0c;设置了条件判断如正则表达式&#xff0c;若用户输入的数据不合法&#xff0c;则添加失败并提示用户错误的地方&#xff0c;便于用户修…

Commonjs与ES Module

commonjs 1 commonjs 实现原理 commonjs每个模块文件上存在 module&#xff0c;exports&#xff0c;require三个变量,然而这三个变量是没有被定义的&#xff0c;但是我们可以在 Commonjs 规范下每一个 js 模块上直接使用它们。在 nodejs 中还存在 __filename 和 __dirname 变…

异常检测-T² (Hotelling‘s T-squared) 统计量和SPE (Squared Prediction Error) 统计量

T 统计量和 SPE 统计量 一、T (Hotellings T-squared) 统计量:二、SPE (Squared Prediction Error) 统计量: 基于主成分分析 (PCA) 的故障诊断是一种常见的统计方法&#xff0c;用于检测和识别过程中的异常情况。在这种方法中&#xff0c;T (Hotelling’s T-squared) 统计量和S…

2021年12月 Python(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python编程&#xff08;1~6级&#xff09;全部真题・点这里 C/C编程&#xff08;1~8级&#xff09;全部真题・点这里 一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 执行以下程序 a[33,55,22,77] a.sort() for i in a:print(i)运行…

C语言 驼峰命名法和下划线命名法

在C语言中&#xff0c;变量命名遵循以下规则&#xff1a; 变量名只能由字母、数字和下划线组成。变量名必须以字母或下划线开头。变量名不能使用C语言中的关键字。变量名中不能出现连续的两个下划线。变量名区分大小写&#xff0c;例如&#xff0c;count和Count被视为两个不同…