Java 弗林克:有没有其他方法来计算平均值和状态变量,而不是使用RichAggregateFunction?
我不确定我必须使用哪个stream Flink转换来计算某个流的平均值,并在5秒内更新一个状态(假设它是一个INT数组,我的状态)。 如果我使用Java 弗林克:有没有其他方法来计算平均值和状态变量,而不是使用RichAggregateFunction?,java,apache-flink,Java,Apache Flink,我不确定我必须使用哪个stream Flink转换来计算某个流的平均值,并在5秒内更新一个状态(假设它是一个INT数组,我的状态)。 如果我使用RichFlatMapFunction我可以计算平均值并更新数组状态。但是,我必须打电话 streamSource .keyBy(0) .flatMap(new MyRichFlatMapFunction()) .print() 我不能把它写在窗户上。 如果我使用 streamSource .keyBy(0) .
RichFlatMapFunction
我可以计算平均值并更新数组状态。但是,我必须打电话
streamSource
.keyBy(0)
.flatMap(new MyRichFlatMapFunction())
.print()
我不能把它写在窗户上。
如果我使用
streamSource
.keyBy(0)
.window(TumblingProcessingTimeWindows.of(Time.seconds(5)))
.aggregate(new MyAggregateFunction())
.print()
我无法通过ValueState
保持数组状态
我试图使用RichAggregateFunction
,但我遇到了与此线程相同的问题。有没有其他方法来计算平均值并跟踪Flink中的另一个状态
在弗林克,我将如何处理这个问题?
以下是我尝试的方法,但实际上不起作用>
streamStations.filter(新的传感器过滤器(“计数”)
.map(新火车站地图())
.keyBy(新的MyKeySelector())
.window(tumblingeventimeewindows.of(Time.seconds(5));
//这个集合不起作用
//.aggregate(新的AverageRichAggregator())
//.print();
公共静态类AverageRichAggregator扩展
RichAggregateFunction{
私有静态最终长serialVersionUID=-4087448912082797L;
私有字符串函数名;
私人价值州countMinSketchState;
@凌驾
公共void open(配置参数)引发异常{
ValueStateDescriptor描述符=新的ValueStateDescriptor(“countMinSketchState”,
CountMinSketch.class);
this.countMinSketchState=getRuntimeContext().getState(描述符);
}
@凌驾
公共元组3 createAccumulator(){
this.countMinSketchState.clear();
返回新的Tuple3(0.0,0L,0);
}
@凌驾
公共元组3添加(
Tuple3值,
三元组(累加器){
试一试{
if(value.f1.f1等于(“COUNT_PE”)){
//int count=(int)Math.round(value.f2);
//countMinSketch.updateSketchAsync(“COUNT_PE”);
}else if(value.f1.f1.equals(“COUNT_TI”)){
//int count=(int)Math.round(value.f2);
//countMinSketch.updateSketchAsync(“COUNT_TI”);
}else if(value.f1.f1.equals(“COUNT_TR”)){
//int count=(int)Math.round(value.f2);
//countMinSketch.updateSketchAsync(“COUNT_TR”);
}
CountMinSketch currentCountMinSketchState=this.countMinSketchState.value();
currentCountMinSketchState.UpdateSketchSync(值为.f1.f1);
this.countMinSketchState.update(currentCountMinSketchState);
}捕获(IOE异常){
e、 printStackTrace();
}
返回新的Tuple3(acculator.f0+value.f2,acculator.f1+1L,value.f1.f4);
}
@凌驾
公共Tuple2 getResult(Tuple3累加器){
字符串标签=”;
整数频率=0;
试一试{
if(functionName.equals(“COUNT_PE”)){
label=“火车站平均人数”;
//frequency=countMinSketch.getFrequencyFromSketch(“COUNT_PE”);
}else if(functionName.equals(“COUNT_TI”)){
标签=“火车站平均车票”;
//frequency=countMinSketch.getFrequencyFromSketch(“COUNT_TI”);
}else if(functionName.equals(“COUNT_TR”)){
标签=“列车在火车站的平均值”;
//frequency=countMinSketch.getFrequencyFromSketch(“COUNT_TR”);
}
frequency=this.countMinSketchState.value().getFrequencyFromSketch(函数名);
}捕获(IOE异常){
e、 printStackTrace();
}
返回新的元组2(标签+“[”+accumulator.f2+”]读取[“+频率+”],
((双)累加器.f0)/累加器.f1);
}
@凌驾
公共元组3合并(元组3 a、元组3 b){
返回新的Tuple3(a.f0+b.f0,a.f1+b.f1,a.f2);
}
}
错误:
Exception in thread "main" java.lang.UnsupportedOperationException: This aggregation function cannot be a RichFunction.
at org.apache.flink.streaming.api.datastream.WindowedStream.aggregate(WindowedStream.java:692)
at org.sense.flink.examples.stream.MultiSensorMultiStationsReadingMqtt2.<init>(MultiSensorMultiStationsReadingMqtt2.java:71)
at org.sense.flink.App.main(App.java:141)
线程“main”java.lang.UnsupportedOperationException中的异常:此聚合函数不能是RichFunction。
位于org.apache.flink.streaming.api.datastream.WindowedStream.aggregate(WindowedStream.java:692)
位于org.sense.flink.examples.stream.MultiSensorMultiStationsReadingMqtt2。(MultiSensorMultiStationsReadingMqtt2.java:71)
位于org.sense.flink.App.main(App.java:141)
谢谢,聚合器不允许保持任意状态,以防聚合器可能与合并窗口一起使用——因为Flink不知道如何合并您的临时状态 但您可以将AggregateFunction与ProcessWindowFunction组合,如下所示:
input
.keyBy(<key selector>)
.timeWindow(<duration>)
.aggregate(new MyAggregateFunction(), new MyProcessWindowFunction());
输入
.keyBy()
.timeWindow()
.aggregate(新的MyAggregateFunction(),新的MyProcessWindowFunction());
ProcessWindowFunction的process方法将被传递一个迭代器,该迭代器只包含预聚合的结果和一个。希望这将以一种简单的方式提供您所需要的。但是,如果您需要用每个到达的记录更新自己的状态,那么您需要扩展聚合器管理的类型以适应这种情况
以下是如何使用全局状态的大致概述:
private static class MyWindowFunction extends ProcessWindowFunction<IN, OUT, KEY, TimeWindow> {
private final static ValueStateDescriptor<Long> myGlobalState =
new ValueStateDescriptor<>("stuff", LongSerializer.INSTANCE);
@Override
public void process(KEY key, Context context, Iterable<IN> values, Collector<OUT> out) {
ValueState<Long> goodStuff = context.globalState().getState(myGlobalState);
}
}
私有静态类MyWindowFunction扩展了ProcessWindowFunction{
私有最终静态值StateDescriptor myGlobalState=
新的ValueStateDescriptor(“stuff”,lonserializer.INSTANCE);
@凌驾
公共void进程(键、上下文上下文、Iterable值、收集器输出){
ValueState goodStuff=context.g
private static class MyWindowFunction extends ProcessWindowFunction<IN, OUT, KEY, TimeWindow> {
private final static ValueStateDescriptor<Long> myGlobalState =
new ValueStateDescriptor<>("stuff", LongSerializer.INSTANCE);
@Override
public void process(KEY key, Context context, Iterable<IN> values, Collector<OUT> out) {
ValueState<Long> goodStuff = context.globalState().getState(myGlobalState);
}
}