Google cloud dataflow 如何使用Apache Beam计算运行总数

Google cloud dataflow 如何使用Apache Beam计算运行总数,google-cloud-dataflow,Google Cloud Dataflow,使用ApacheBeamSDK for Google数据流,我想计算一组事务的每日余额 示例数据集可能与收款人姓名、交易日期和金额类似: John, 2017-12-01, 100 John, 2017-12-01, 200 Jane, 2017-12-01, 150 John, 2017-12-02, -100 John, 2017-12-02, 300 所需的结果集如下所示: John, 2017-12-01, 300 (100 + 200) Jane, 2017-12-01, 150

使用ApacheBeamSDK for Google数据流,我想计算一组事务的每日余额

示例数据集可能与收款人姓名、交易日期和金额类似:

John, 2017-12-01, 100
John, 2017-12-01, 200
Jane, 2017-12-01, 150
John, 2017-12-02, -100
John, 2017-12-02, 300
所需的结果集如下所示:

John, 2017-12-01, 300  (100 + 200)
Jane, 2017-12-01, 150
John, 2017-12-02, 500  (300 + -100 + 300)

我曾尝试使用
KV
Combine.perKey
函数来计算
BigDecimal
的总和,但这并不能将前一天的期末余额作为第二天的起始余额。

Beam的窗口API在这里使用是正确的:

具体而言,您必须回答以下问题:

  • 您希望在事件发生时在何处执行聚合?
  • 在处理时间内,您想要您的答案吗?
  • 您的帖子中没有足够的信息来回答这些问题-您必须提供更多的细节-您是以批处理模式还是流式模式运行?您是希望在每天结束时得到一个答案,还是希望每次有新的交易时都能得到更新的运行总数?还是介于两者之间?如果非要我猜的话,听起来您希望保留一个全局总计(全局事件时间窗口),并每天更新一次当前值

    在回答了上述问题之后,我们可以编写一些伪代码:

    PCollection<KV<String, Double>> transactionsByName = .... ;     // Read input
    
    PCollection<KV<String, Double> dailyTotalsByName = transactionsByName
      // Group by name
      .apply(GroupByKey.<String, Double>create())   
      // 1-day windows       
      .apply(Window.<KV<String, Iterable<Double>>>into(    
          FixedWindows.of(Duration.standardDays(1))))    
      // Combine each window (see combiners guide [here][1])  
      .apply(Combine.<String, Iterable<Double>, Double>perKey(new SumTotals())); 
    
    PCollection<KV<String, Double> globalTotalsByName = dailyTotalsByName
      // Global windows allow you to combine a running total. Triggering condition
      // specifies 'when' in processing time the answers are materialized. Here we
      // have chosen to output the answer each time a new daily total arrives.
      .apply(Window.<KV<String, Iterable<Double>>>into(new GlobalWindows()))
         .triggering(Repeatedly.forever(AfterPane.elementCountAtLeast(1))))
      // Combine daily totals
      .apply(Combine.<String, Iterable<Double>, Double>perKey(new SumTotals()))
    
    PCollection transactionsByName=..;//读取输入
    
    谢谢你的回复。我描述的过程是一个有界的批处理过程。它以特定的时间表(可能是任何时候)从Bigtable表读取数据,计算每日余额,并将结果写入另一个Bigtable表。关于窗口化,我的印象是,这与收集元素的时间戳有关,而不是任意的数据元素。可能是这个过程现在正在处理日期在过去的数据元素。也许您是建议我需要手动为元素分配时间戳,如中所述。另外,您可以扩展SumTotals()类,特别是它扩展或实现的内容及其签名。我无法找到可编译的解决方案。在全局窗口中保存状态的另一个重要方法是如何对其进行垃圾收集: