Apache Flink 官方文档提供了广播状态的功能以及有关 API 的详细指南。在使用广播状态时要记住以下4个重要事项:
- 使用广播状态,operator task 之间不会相互通信
- 广播状态中事件的顺序在各个并发实例中可能不尽相同
- 所有 operator task 都会快照下他们的广播状态
- RocksDB 状态后端目前还不支持广播状态
广播变量创建后,它可以运行在集群中的任何function上,而不需要多次传递给集群节点。
另外需要记住,不应该修改广播变量,这样才能确保每个节点获取到的值都是一致的。
一句话解释,可以理解为是一个公共的共享变量,我们可以把一个dataset 数据集广播出去,然后不同的task在节点上都能够获取到,这个数据在每个节点上只会存在一份,节约内存。
用法
- 1、定义一个MapStateDescriptor来描述我们要广播的数据的格式
- 2、需要一个Stream来广播下游的operator
- 3、添加数据源并把数据源注册成广播流
- 4、连接广播流和处理数据的流
示例
1、flink batch
package flink.batch;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.common.functions.RichMapFunction;
import org.apache.flink.api.java.DataSet;
import org.apache.flink.api.java.ExecutionEnvironment;
import org.apache.flink.api.java.operators.DataSource;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.configuration.Configuration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* broadcast广播变量
*
* 需求:
* flink会从数据源中获取到用户的姓名
* 最终需要把用户的姓名和年龄信息打印出来
*
* 所以就需要在中间map处理的时候,就需要获取用户的年龄信息
* 建议将用户的关系数据集使用广播变量进行处理
*
*
* 注意:如果多个算子需要使用同一份数据集,那么需要在对应的多个算子后面分别注册广播变量
*/
public class BatchDemoBroadcast {
public static void main(String[] args) throws Exception {
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
//1、准备广播变量的数据
ArrayList<Tuple2<String, Integer>> broadData = new ArrayList<>();
broadData.add(new Tuple2<>("python",18));
broadData.add(new Tuple2<>("scala",20));
broadData.add(new Tuple2<>("java",17));
DataSource <Tuple2 <String, Integer>> dataBroad = env.fromCollection(broadData);
//2、对需要广播的数据进行处理,将tuple2类型转换成hashMap类型
DataSet<HashMap <String, Integer>> baseData = dataBroad.map(new MapFunction <Tuple2 <String, Integer>, HashMap <String, Integer>>() {
@Override
public HashMap <String, Integer> map(Tuple2 <String, Integer> value) throws Exception {
HashMap <String, Integer> res = new HashMap <>();
res.put(value.f0, value.f1);
return res;
}
});
DataSet <String> mainData = env.fromElements("python", "java","java","kafka","scala","redis");
DataSet <String> result = mainData.map(new RichMapFunction <String, String>() {
List <HashMap <String, Integer>> broadCastMap = new ArrayList <HashMap <String, Integer>>();
HashMap <String, Integer> allMap = new HashMap <String, Integer>();
/**
* 这个方法只会执行一次
* 可以在这里实现一些初始化的功能
*
* 所以,就可以在open方法中获取广播变量数据
*
*/
@Override
public void open(Configuration parameters) throws Exception {
super.open(parameters);
//3:获取广播数据
this.broadCastMap = getRuntimeContext().getBroadcastVariable("broadCastMapName");
for (HashMap map : broadCastMap) {
allMap.putAll(map);
}
}
@Override
public String map(String value) throws Exception {
Integer age = allMap.get(value);
return value + "," + age;
}
}).withBroadcastSet(baseData,"broadCastMapName");
result.print();
}
}
2、flink stream
package flink.stream.a

本文深入探讨了Apache Flink中的广播状态功能,包括其工作原理、使用限制以及如何在批处理和流处理中应用。通过具体示例展示了如何定义广播状态、将其与数据流连接以及在任务中使用。
最低0.47元/天 解锁文章
2848

被折叠的 条评论
为什么被折叠?



