sunny123456

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

Flink AggregatingState 实例

AggregatingState介绍

  • AggregatingState需要和AggregateFunction配合使用
  • add()方法添加一个元素,触发AggregateFunction计算
  • get()获取State的值

需求:计算每个设备10秒内的平均温度

  1. import org.apache.flink.api.common.eventtime.SerializableTimestampAssigner;
  2. import org.apache.flink.api.common.eventtime.WatermarkStrategy;
  3. import org.apache.flink.api.common.functions.AggregateFunction;
  4. import org.apache.flink.api.common.state.AggregatingState;
  5. import org.apache.flink.api.common.state.AggregatingStateDescriptor;
  6. import org.apache.flink.api.common.typeinfo.TypeHint;
  7. import org.apache.flink.api.common.typeinfo.TypeInformation;
  8. import org.apache.flink.api.java.functions.KeySelector;
  9. import org.apache.flink.api.java.tuple.Tuple2;
  10. import org.apache.flink.api.java.tuple.Tuple3;
  11. import org.apache.flink.configuration.Configuration;
  12. import org.apache.flink.streaming.api.datastream.DataStreamSource;
  13. import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
  14. import org.apache.flink.streaming.api.functions.KeyedProcessFunction;
  15. import org.apache.flink.streaming.api.functions.source.SourceFunction;
  16. import org.apache.flink.util.Collector;
  17. import java.time.Duration;
  18. import java.util.Random;
  19. public class AggregatingStateTest {
  20. public static void main(String[] args) throws Exception {
  21. // 计算每个设备10s内温度的平均值
  22. StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
  23. env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
  24. env.getConfig().setAutoWatermarkInterval(100l);
  25. DataStreamSource<Tuple3<String, Integer, Long>> tuple3DataStreamSource = env.addSource(new SourceFunction<Tuple3<String, Integer, Long>>() {
  26. boolean flag = true;
  27. @Override
  28. public void run(SourceContext<Tuple3<String, Integer, Long>> ctx) throws Exception {
  29. String[] str = {"水阀1", "水阀2", "水阀3"};
  30. while (flag) {
  31. int i = new Random().nextInt(3);
  32. // 温度
  33. int temperature = new Random().nextInt(100);
  34. Thread.sleep(1000l);
  35. // 设备号、温度、事件时间
  36. ctx.collect(new Tuple3<String, Integer, Long>(str[i], temperature, System.currentTimeMillis()));
  37. }
  38. }
  39. @Override
  40. public void cancel() {
  41. flag = false;
  42. }
  43. });
  44. tuple3DataStreamSource.assignTimestampsAndWatermarks(WatermarkStrategy.<Tuple3<String, Integer, Long>>forBoundedOutOfOrderness(Duration.ofSeconds(2))
  45. .withTimestampAssigner(new SerializableTimestampAssigner<Tuple3<String, Integer, Long>>() {
  46. @Override
  47. public long extractTimestamp(Tuple3<String, Integer, Long> stringIntegerLongTuple3, long l) {
  48. return stringIntegerLongTuple3.f2;
  49. }
  50. })).keyBy(new KeySelector<Tuple3<String, Integer, Long>, String>() {
  51. @Override
  52. public String getKey(Tuple3<String, Integer, Long> stringIntegerLongTuple3) throws Exception {
  53. return stringIntegerLongTuple3.f0;
  54. }
  55. }).process(new KeyedProcessFunction<String, Tuple3<String, Integer, Long>, String>() {
  56. Long interval = 10 * 1000l;
  57. // <Integer, Double>这个类型是aggregatingState中的输入和输出类型
  58. AggregatingState<Integer, Double> aggregatingState = null;
  59. @Override
  60. public void open(Configuration parameters) throws Exception {
    1. @Override
    2. public void open(Configuration parameters) throws Exception {
    super.open(parameters);
  61. // <Integer, Tuple2<Integer,Integer>, Double>这是输入,中间状态,输出类型。TypeInformation.of(new TypeHint<Tuple2<Integer,Integer>>(){})这个是aggregatingState存储的数据的类型
  62. AggregatingStateDescriptor<Integer, Tuple2<Integer,Integer>, Double> aggregatingStateDescriptor =
  63. new AggregatingStateDescriptor<Integer, Tuple2<Integer,Integer>, Double>("aggregatingState", new MyAggregate(), TypeInformation.of(new TypeHint<Tuple2<Integer,Integer>>(){}));
  64. aggregatingState = getRuntimeContext().getAggregatingState(aggregatingStateDescriptor);
  65. }
  66. @Override
  67. public void processElement(Tuple3<String, Integer, Long> value, Context ctx, Collector<String> out) throws Exception {
  68. // 10s的起始的时间
  69. Long start = ctx.timestamp() - (ctx.timestamp() % interval);
  70. Long timerTimestamp = start + interval;
  71. ctx.timerService().registerEventTimeTimer(timerTimestamp);
  72. aggregatingState.add(value.f1);
  73. }
  74. @Override
  75. public void onTimer(long timestamp, OnTimerContext ctx, Collector<String> out) throws Exception {
  76. super.onTimer(timestamp, ctx, out);
  77. Double aDouble = aggregatingState.get();
  78. String str = "[" + ctx.getCurrentKey() + "] " + "十秒内的平均温度为:" + aDouble;
  79. out.collect(str);
  80. }
  81. }).print();
  82. env.execute("aggregatingState");
  83. }
  84. private static class MyAggregate implements AggregateFunction<Integer, Tuple2<Integer,Integer>, Double> {
  85. @Override
  86. public Tuple2<Integer, Integer> createAccumulator() {
  87. // 初始化温度和次数
  88. return new Tuple2<Integer, Integer>(0,0);
  89. }
  90. @Override
  91. public Tuple2<Integer, Integer> add(Integer integer, Tuple2<Integer, Integer> integerIntegerTuple2) {
  92. // 历史温度加上本次温度,次数加1
  93. return new Tuple2<Integer, Integer>(integerIntegerTuple2.f0 + integer, integerIntegerTuple2.f1 +1);
  94. }
  95. @Override
  96. public Double getResult(Tuple2<Integer, Integer> integerIntegerTuple2) {
  97. return Double.valueOf(integerIntegerTuple2.f0 / integerIntegerTuple2.f1);
  98. }
  99. @Override
  100. public Tuple2<Integer, Integer> merge(Tuple2<Integer, Integer> integerIntegerTuple2, Tuple2<Integer, Integer> acc1) {
  101. return new Tuple2<Integer, Integer>(integerIntegerTuple2.f0 + acc1.f0, integerIntegerTuple2.f1 + acc1.f1);
  102. }
  103. }
  104. }

原文链接:https://blog.csdn.net/qq_35514685/article/details/124351482
posted on 2024-03-06 16:38  sunny123456  阅读(18)  评论(0编辑  收藏  举报