Apache flink Flink执行数据流两次

Apache flink Flink执行数据流两次,apache-flink,Apache Flink,我是Flink的新手,我使用数据集API。作为最后一个阶段,经过一系列处理之后,我需要通过将其中一个值除以其最大值来对其进行规范化。因此,我使用了.max()操作符来获取max,然后将结果作为构造函数的参数传递给MapFunction 这是可行的,但是所有处理都要执行两次。执行一个作业以查找最大值,然后执行另一个作业以创建最终结果(从头开始执行)。。。是否存在只执行一次整个数据流的变通方法 final List<Tuple6<...>> maxValues = res

我是Flink的新手,我使用数据集API。作为最后一个阶段,经过一系列处理之后,我需要通过将其中一个值除以其最大值来对其进行规范化。因此,我使用了
.max()
操作符来获取max,然后将结果作为构造函数的参数传递给MapFunction

这是可行的,但是所有处理都要执行两次。执行一个作业以查找最大值,然后执行另一个作业以创建最终结果(从头开始执行)。。。是否存在只执行一次整个数据流的变通方法

  final List<Tuple6<...>> maxValues = result.max(2).collect();
  assert maxValues.size() == 1;
  result.map(new NormalizeAttributes(maxValues.get(0))).writeAsCsv(...)

@FunctionAnnotation.ForwardedFields("f0; f1; f3; f4; f5")
@FunctionAnnotation.ReadFields("f2")
private static class NormalizeAttributes implements MapFunction<Tuple6<...>, Tuple6<...>> {

    private final Tuple6<...> maxValues;

    public NormalizeAttributes(Tuple6<...> maxValues) {
        this.maxValues = maxValues;
    }

    @Override
    public Tuple6<...> map(Tuple6<...> value) throws Exception {
        value.f2 /= maxValues.f2;
        return value;
    }
}
final List maxValues=result.max(2.collect();
断言maxValues.size()==1;
result.map(新的NormalizeAttributes(maxValues.get(0)).writeAsCsv(…)
@FunctionAnnotation.ForwardedFields(“f0;f1;f3;f4;f5”)
@FunctionAnnotation.ReadFields(“f2”)
私有静态类NormalizeAttributes实现MapFunction{
私有最终Tuple6最大值;
公共属性(Tuple6最大值){
this.maxValues=maxValues;
}
@凌驾
公共Tuple6映射(Tuple6值)引发异常{
value.f2/=maxValues.f2;
返回值;
}
}
collect()
立即触发程序的执行,直到
collect()
请求的数据集为止。如果以后再次调用
env.execute()
collect()
,程序将再次执行

除了执行的副作用外,使用
collect()
将值分配给后续转换还有一个缺点,即数据传输到客户机,然后再返回集群。Flink提供了所谓的广播变量,将
数据集
作为侧面输入发送到另一个转换中

在程序中使用广播变量如下所示:

DataSet maxValues = result.max(2);
result
  .map(new NormAttrs()).withBroadcastSet(maxValues, "maxValues")
  .writeAsCsv(...);
NormAttrs
函数如下所示:

private static class NormAttr extends RichMapFunction<Tuple6<...>, Tuple6<...>> {

  private Tuple6<...> maxValues;

  @Override
  public void open(Configuration config) {
    maxValues = (Tuple6<...>)getRuntimeContext().getBroadcastVariable("maxValues").get(1);
  }

  @Override
  public PredictedLink map(Tuple6<...> value) throws Exception {
    value.f2 /= maxValues.f2;
    return value;
  }
}
私有静态类NormAttr扩展了RichMapFunction{
私有Tuple6最大值;
@凌驾
公共无效打开(配置){
maxValues=(Tuple6)getRuntimeContext().getBroadcastVariable(“maxValues”).get(1);
}
@凌驾
公共PredictedLink映射(Tuple6值)引发异常{
value.f2/=maxValues.f2;
返回值;
}
}
您可以在中找到有关广播变量的详细信息。

collect()
会立即触发程序的执行,直到
collect()
请求的数据集。如果以后再次调用
env.execute()
collect()
,程序将再次执行

除了执行的副作用外,使用
collect()
将值分配给后续转换还有一个缺点,即数据传输到客户机,然后再返回集群。Flink提供了所谓的广播变量,将
数据集
作为侧面输入发送到另一个转换中

在程序中使用广播变量如下所示:

DataSet maxValues = result.max(2);
result
  .map(new NormAttrs()).withBroadcastSet(maxValues, "maxValues")
  .writeAsCsv(...);
NormAttrs
函数如下所示:

private static class NormAttr extends RichMapFunction<Tuple6<...>, Tuple6<...>> {

  private Tuple6<...> maxValues;

  @Override
  public void open(Configuration config) {
    maxValues = (Tuple6<...>)getRuntimeContext().getBroadcastVariable("maxValues").get(1);
  }

  @Override
  public PredictedLink map(Tuple6<...> value) throws Exception {
    value.f2 /= maxValues.f2;
    return value;
  }
}
私有静态类NormAttr扩展了RichMapFunction{
私有Tuple6最大值;
@凌驾
公共无效打开(配置){
maxValues=(Tuple6)getRuntimeContext().getBroadcastVariable(“maxValues”).get(1);
}
@凌驾
公共PredictedLink映射(Tuple6值)引发异常{
value.f2/=maxValues.f2;
返回值;
}
}
您可以在中找到有关广播变量的更多信息