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