Java 在Apache FLink中计算不同窗口上的度量

Java 在Apache FLink中计算不同窗口上的度量,java,apache-flink,Java,Apache Flink,我正在使用Apache Flink 1.2,下面是我的问题: 我有一个数据流,我想在一天的时间内计算一个度量。因此,我将写下如下内容: DataStream<Tuple6<Timestamp, String, Double, Double, Double, Integer>> myStream0 = env.readTextFile("Myfile.csv") .map(new MyMapper())

我正在使用Apache Flink 1.2,下面是我的问题: 我有一个数据流,我想在一天的时间内计算一个度量。因此,我将写下如下内容:

DataStream<Tuple6<Timestamp, String, Double, Double, Double, Integer>> myStream0 = 
            env.readTextFile("Myfile.csv")
            .map(new MyMapper())                // Parse the input
            .assignTimestampsAndWatermarks(new MyExtractor())   //Assign the timestamp of the event 
            .timeWindowAll(Time.days(1))    
            .apply(new average());  // compute average, max, sum
DataStream myStream0=
env.readTextFile(“Myfile.csv”)
.map(新的MyMapper())//解析输入
.assignTimestampsAndWatermarks(new MyExtractor())//分配事件的时间戳
.timeWindowAll(Time.days(1))
.应用(新平均值());//计算平均值、最大值、总和
现在我想在1小时内计算相同的度量


我可以编写与以前相同的代码,并指定Time.hours(1),但我担心的是,通过这种方式,ApacheFlink会读取两倍的输入文件,并执行两倍的工作。我想知道是否有一种方法可以把所有的事情都放在一起(即使用同一条流)。

你可以计算每小时的总量,并从中计算出每天的总量。这将查找一个简单的
数据流
,如下所示:

DataStream<Double> vals = ... // source + timestamp extractor

DataStream<Tuple2<Double, Long>> valCnt = vals // (sum, cnt)
  .map(new CntAppender())     // Double -> Tuple2<Double, Long(1)>

DataStream<Tuple3<Double, Long, Long>> hourlySumCnt = valCnt // (sum, cnt, endTime)
  .timeWindowAll(Time.hours(1))
  // SumCounter ReduceFunction sums the Double and Long field (Long is Count)
  // WindowEndAppender WindowFunction adds the window end timestamp (3rd field)
  .reduce(new SumCounter(), new WindowEndAppender())   

DataStream<Tuple2<Double, Long>> hourlyAvg = hourlySumCnt // (avg, endTime)
  .map(new SumDivCnt()) // MapFunction divides Sum by Cnt for average

DataStream<Tuple3<Double, Long, Long>> dailySumCnt = hourlySumCnt // (sum, cnt, endTime)
  .map(new StripeOffTime()) // removes unnecessary time field -> Tuple2<Double, Long>
  .timeWindowAll(Time.days(1))
  .reduce(new SumCounter(), new WindowEndAppender()) // same as above

DataStream<Tuple2<Double, Long>> dailyAvg = dailySumCnt // (avg, endTime)
  .map(new SumDivCnt()) // same as above
DataStream vals=…//源+时间戳提取器
数据流valCnt=VAL/(总和,cnt)
.map(新的cntpender())//Double->Tuple2
DataStream hourlySumCnt=valCnt/(求和,cnt,endTime)
.timeWindowAll(Time.hours(1))
//SumCounter ReduceFunction对Double和Long字段求和(Long是计数)
//WindowEndAppender WindowFunction添加窗口结束时间戳(第三个字段)
.reduce(新的SumCounter(),新的WindowEndAppender())
数据流hourlyAvg=hourlySumCnt/(平均值,结束时间)
.map(new SumDivCnt())//MapFunction将Sum除以Cnt求平均值
DataStream dailySumCnt=hourlySumCnt//(总和,cnt,结束时间)
.map(new StripeOffTime())//删除不必要的时间字段->Tuple2
.timeWindowAll(Time.days(1))
.reduce(新的SumCounter(),新的WindowEndAppender())//同上
数据流dailyAvg=dailySumCnt/(平均值,结束时间)
.map(新的SumDivCnt())//同上
所以,你们基本上计算每小时的总和和计数,然后根据这个结果你们就可以

  • 计算每小时平均值
  • 计算每日总和和计数以及每日平均值
  • 请注意,我使用的是
    ReduceFunction
    而不是
    WindowFunction
    进行求和和和计数计算,因为
    ReduceFunction
    是迫切需要应用的,即窗口的所有记录都不会被收集,而是立即聚合。因此,需要维护的状态是单个记录