Flink的广播变量

使用过spark的人都知道广播变量这个概念。广播变量相当于一个共享变量,将一个小数据集复制分发到每个task,task直接从本地读取。flink中有两种广播变量,一种静态的广播变量,一种实时动态的广播变量。

    静态广播变量示例:

      Broadcast(广播数据) :通过withBroadcastSet(DataSet, String) 进行广播数据,并给这份数据起名字
      Access(获取数据):通过getRuntimeContext().getBroadcastVariable(String)获取广播出去的数据
 

     使用场景如: 黑名单判断,将黑名单广播出去进行数据匹配。

public class FlinkBroadcast2 {
    public static void main(String[] args) throws Exception {
        ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
        DataSet<Integer> ds1 = env.fromElements(1, 2, 3, 4);
        DataSource<Integer> ds2 = env.fromElements(7, 8, 9, 10);
        ds2.map(new RichMapFunction<Integer, String>() {
            List<Integer> list = new ArrayList<Integer>();
            public void open(Configuration parameters) throws Exception {
               list = getRuntimeContext().getBroadcastVariable("bs");
            }
 
            @Override
            public String map(Integer integer) throws Exception {
 
                return integer.intValue()+":"+list;
            }
        }).withBroadcastSet(ds1,"bs").print();
 
//       env.execute();
    }

当然,其中的map也可以替换其他的filter等方法,只不过还是实现其对应的Rich方法。

注意:

1:广播出去的变量存在于每个节点的内存中,所以这个数据集不能太大。因为广播出去的数据,会常驻内存,除非程序执行结束。

2:广播变量在初始化广播出去以后不支持修改,这样才能保证每个节点的数据都是一致的。

个人建议:如果数据集在几十兆或者百兆的时候,可以选择进行广播,如果数据集的大小上G的话,就不建议进行广播了。

 动态广播变量示例:

   使用场景: 数据依赖某些动态变化的处理规则

   广播流一般都是从kafka或其他数据源获取,这里演示直接固定了。从kafka获取流,修改数据后,下游也会更新广播流。

   key streaming 使用KeyedBroadcastProcessFunction.

   非key streaming 使用 BroadcastProcessFunction.

public class FlinkBroadcast {
    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(1);
        DataStream<Integer> ds1 = env.fromElements(2);
        DataStreamSource<Integer> ds2 = env.fromElements(7,8,9,10);
        MapStateDescriptor<String, Integer> ruleStateDescriptor = new MapStateDescriptor<>(
                "BroadcastState",
                BasicTypeInfo.STRING_TYPE_INFO,
                TypeInformation.of(Integer.TYPE));
 
        BroadcastStream<Integer> ruleBroadcastStream = ds1
                .broadcast(ruleStateDescriptor);
         ds2.connect(ruleBroadcastStream)
                .process(
 
 
                        new BroadcastProcessFunction<Integer,Integer,String>() {
 
                            @Override
                            public void processElement(Integer integer, ReadOnlyContext readOnlyContext, Collector<String> collector) throws Exception {
                                ReadOnlyBroadcastState<String, Integer> state = readOnlyContext.getBroadcastState(ruleStateDescriptor);
                                Integer integer1 = state.get("test");
                                collector.collect(integer+"="+integer1);
                            }
 
                            @Override
                            public void processBroadcastElement(Integer integer, Context context, Collector<String> collector) throws Exception {
                                context.getBroadcastState(ruleStateDescriptor).put("test",integer);
                            }
                        }
                ).print();
      env.execute();
    }
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值