Tutorial do Flink (17) Caso de uso AggregatingState de gerenciamento de estado com chave para encontrar o valor médio

Série de artigos

Tutorial Flink (13) Gerenciamento de estado de estado com chave ValueState usando alarme de diferença de temperatura
Tutorial de Flink (14) caso de uso de MapState de gerenciamento de estado com chave
Tutorial de Flink (15) gerenciamento de estado de estado com chave ListState usando ValueState para implementar
tutorial de Flink (16) estado de estado com chave The ReducingState caso de uso de gerenciamento para encontrar o valor máximo
Flink tutorial (17) O caso de uso AggregatingState de gerenciamento de estado com chave para encontrar o valor médio

Um, o método de AggregatingState

  • AggregatingState precisa ser usado em conjunto com AggregateFunction
  • O método add () adiciona um elemento para acionar o cálculo AggregateFunction
  • get () Pega o valor de State
    Insira a descrição da imagem aqui

Dois, descritor AggregatingState

Ao definir o descritor, o segundo parâmetro requer a classe AggregateFunction

//定义描述器
AggregatingStateDescriptor aggregatingStateDescriptor = new AggregatingStateDescriptor(
         "avg-temp",
         new SensorRecordUtils.MyAvgTemp(),
         TypeInformation.of(new TypeHint<Tuple2<Double, Integer>>(){
    
    })
 );

//获取ReducingState
aggregatingState = getRuntimeContext().getAggregatingState(aggregatingStateDescriptor);

Terceiro, a classe AggregateFunction personalizada

Flink calcula o valor médio.O primeiro parâmetro da Tupla2 é a soma da temperatura atual e o segundo parâmetro é o número de dados.

Accumulator.f0 / Accumulator.f1 em getResult obtém o valor médio.

public static class MyAvgTemp implements AggregateFunction<SensorRecord, Tuple2<Double, Integer>, Double> {
    
    

    @Override
    public Tuple2<Double, Integer> createAccumulator() {
    
    
        return Tuple2.of(0.0, 0);
    }

    @Override
    public Tuple2<Double, Integer> add(SensorRecord value, Tuple2<Double, Integer> accumulator) {
    
    
        Integer currentCount = accumulator.f1;
        currentCount += 1;
        accumulator.f1 = currentCount;
        return new Tuple2<>(accumulator.f0 + value.getRecord(), accumulator.f1);
    }

    @Override
    public Double getResult(Tuple2<Double, Integer> accumulator) {
    
    
        return accumulator.f0 / accumulator.f1;
    }

    @Override
    public Tuple2<Double, Integer> merge(Tuple2<Double, Integer> a, Tuple2<Double, Integer> b) {
    
    
        return new Tuple2<>(a.f0 + b.f0, a.f1 + b.f1);
    }
}

Quarto, o corpo principal do programa

public class Test06_AggregatingState {
    
    

    public static void main(String[] args) throws Exception {
    
    

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        //方便测试,设置为1
        env.setParallelism(1);

        DataStreamSource<String> source = env.socketTextStream(BaseConstant.URL, BaseConstant.PORT);

        /*
        设置watermark和指定时间属性
         */
        SingleOutputStreamOperator<SensorRecord> dataStream = source
                .map(new SensorRecordUtils.BeanMap());

        dataStream
                .keyBy(SensorRecord::getId)
                .process(new MyKeyedProcessFunction())
                .print();

        env.execute();
    }
}

Cinco, classe de processamento KeyedProcessFunction

public static class MyKeyedProcessFunction extends KeyedProcessFunction<String, SensorRecord, Tuple2<String, Double>> {
    
    

    private transient AggregatingState aggregatingState;

    @Override
    public void open(Configuration parameters) throws Exception {
    
    
        super.open(parameters);

        //定义描述器
        AggregatingStateDescriptor aggregatingStateDescriptor = new AggregatingStateDescriptor(
                "avg-temp",
                new SensorRecordUtils.MyAvgTemp(),
                TypeInformation.of(new TypeHint<Tuple2<Double, Integer>>(){
    
    })
        );

        //获取ReducingState
        aggregatingState = getRuntimeContext().getAggregatingState(aggregatingStateDescriptor);
    }

    @Override
    public void processElement(SensorRecord value, Context ctx, Collector<Tuple2<String, Double>> out) throws Exception {
    
    

        aggregatingState.add(value);
        out.collect(Tuple2.of(value.getId(), (Double) aggregatingState.get()) );
    }
}

Acho que você gosta

Origin blog.csdn.net/winterking3/article/details/115133519
Recomendado
Clasificación