gpt4 book ai didi

java - 如何在 Fink 中实例化 MapStateDescriptor 来计算多个平均值流查询?

转载 作者:行者123 更新时间:2023-12-02 01:40:20 27 4
gpt4 key购买 nike

我正在尝试计算 3 个不同房间的温度平均值,每个房间有 3 个温度传感器。我正在使用 Flink(Java 语言)。首先,我通过房间(A、B 或 C)这个键来分割传感器,然后我创建一个 RichFlatMapFunction ,它保存一个 MapState 来保存温度,同时我直到 3 次测量为止。经过三次测量后,我计算平均值。为了使用 MapState,我需要一个 MapStateDescriptor,但我不知道如何正确实例化。有人可以帮我弄这个吗?谢谢。

public class SensorsMultipleReadingMqttEdgentQEP2 {

private boolean checkpointEnable = false;
private long checkpointInterval = 10000;
private CheckpointingMode checkpointMode = CheckpointingMode.EXACTLY_ONCE;

public SensorsMultipleReadingMqttEdgentQEP2() throws Exception {

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

env.setStreamTimeCharacteristic(TimeCharacteristic.IngestionTime);

if (checkpointEnable) {
env.enableCheckpointing(checkpointInterval, checkpointMode);
}

DataStream<MqttTemperature> temperatureStream01 = env.addSource(new TemperatureMqttConsumer("topic-edgent-01"));
DataStream<MqttTemperature> temperatureStream02 = env.addSource(new TemperatureMqttConsumer("topic-edgent-02"));
DataStream<MqttTemperature> temperatureStream03 = env.addSource(new TemperatureMqttConsumer("topic-edgent-03"));

DataStream<Tuple2<String, Double>> averageStream01 = temperatureStream01.map(new SensorMatcher()).keyBy(0)
.flatMap(new AverageTempMapper());
DataStream<Tuple2<String, Double>> averageStream02 = temperatureStream02.map(new SensorMatcher()).keyBy(0)
.flatMap(new AverageTempMapper());
DataStream<Tuple2<String, Double>> averageStream03 = temperatureStream03.map(new SensorMatcher()).keyBy(0)
.flatMap(new AverageTempMapper());

DataStream<Tuple2<String, Double>> averageStreams = averageStream01.union(averageStream02)
.union(averageStream03);

averageStreams.print();
env.execute("SensorsMultipleReadingMqttEdgentQEP");
}

public static class SensorMatcher implements MapFunction<MqttTemperature, Tuple2<String, MqttTemperature>> {

private static final long serialVersionUID = 7035756567190539683L;

@Override
public Tuple2<String, MqttTemperature> map(MqttTemperature value) throws Exception {
String key = "no-room";
if (value.getId().equals(1) || value.getId().equals(2) || value.getId().equals(3)) {
key = "room-A";
} else if (value.getId().equals(4) || value.getId().equals(5) || value.getId().equals(6)) {
key = "room-B";
} else if (value.getId().equals(7) || value.getId().equals(8) || value.getId().equals(9)) {
key = "room-C";
} else {
System.err.println("Sensor not defined in any room.");
}
return new Tuple2<>(key, value);
}
}

public static class AverageTempMapper
extends RichFlatMapFunction<Tuple2<String, MqttTemperature>, Tuple2<String, Double>> {

private static final long serialVersionUID = -4780146677198295204L;
private MapState<String, Tuple2<Integer, Double>> modelState;

@Override
public void open(Configuration parameters) throws Exception {
TypeInformation<Tuple2<String, Tuple2<Integer, Double>>> typeInformation = TypeInformation
.of(new TypeHint<Tuple2<String, Tuple2<Integer, Double>>>() {
});

// HOW TO INSTANTIATE THIS descriptor?
MapStateDescriptor<String, Tuple2<Integer, Double>> descriptor = new MapStateDescriptor<>("modelState",
String.class, Tuple2.class);
modelState = getRuntimeContext().getMapState(descriptor);
}

@Override
public void flatMap(Tuple2<String, MqttTemperature> value, Collector<Tuple2<String, Double>> out)
throws Exception {
Double temp = null;
Integer count = 0;
if (modelState.contains(value.f0)) {
count = modelState.get(value.f0).f0 + 1;
temp = (modelState.get(value.f0).f1 + value.f1.getTemp());
} else {
count = 1;
temp = value.f1.getTemp();
}
modelState.put(value.f0, Tuple2.of(count, temp));

if (count >= 3) {
out.collect(Tuple2.of("room", null));
}
}
}
}

最佳答案

为了定义MapStateDescriptor,您可以执行以下操作:

MapStateDescriptor<String, Tuple2<Integer, Double>> modelState = new MapStateDescriptor<>(
"modelState",
BasicTypeInfo.STRING_TYPE_INFO,
TupleTypeInfo.getBasicTupleTypeInfo(Integer.class, Double.class));
this.modelState = getRuntimeContext().getMapState(modelState);

但是,在您的情况下实际上不需要使用 MapState 。由于流已经被设置了键,因此使用 ValueState 就足够了。代码如下所示:

public static class AverageTempMapper extends RichFlatMapFunction<Tuple2<String, MqttTemperature>, Tuple2<String, Double>> {

private static final long serialVersionUID = -4780146677198295204L;
private ValueState<Tuple2<Integer, Double>> modelState;

@Override
public void open(Configuration parameters) {
this.modelState = getRuntimeContext().getState(new ValueStateDescriptor<>("modelState", TupleTypeInfo.getBasicTupleTypeInfo(Integer.class, Double.class)));
}

@Override
public void flatMap(Tuple2<String, MqttTemperature> value, Collector<Tuple2<String, Double>> out) throws Exception {
Double temp;
Integer count;
if (modelState.value() != null) {
Tuple2<Integer, Double> state = modelState.value();
count = state.f0 + 1;
temp = state.f1 + value.f1.getTemp();
} else {
count = 1;
temp = value.f1.getTemp();
}
modelState.update(Tuple2.of(count, temp));

if (count >= 3) {
out.collect(Tuple2.of(value.f0, temp/count));
}
}
}

关于java - 如何在 Fink 中实例化 MapStateDescriptor 来计算多个平均值流查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54535419/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com