此问题的解决方法是使用Beam的窗口和触发器功能。您可以为PCollection应用窗口,并使用触发器来控制何时在无界数据集上触发计算。以下是一个使用窗口和触发器解决此问题的示例代码:
import apache_beam as beam
from apache_beam.transforms.window import TimestampedValue, GlobalWindows
from apache_beam.transforms.trigger import AfterWatermark, AfterProcessingTime, AccumulationMode
class AggregateSum(beam.PTransform):
def expand(self, pcoll):
return (
pcoll
.apply("Add timestamps", beam.Map(lambda elem: TimestampedValue(elem, elem)))
.apply("Apply window", beam.WindowInto(GlobalWindows()))
.apply("Sum", beam.CombineGlobally(sum).without_defaults())
.apply("Format output", beam.Map(lambda elem: f"Total sum: {elem}"))
)
with beam.Pipeline() as p:
result = (
p
.apply("Generate data", beam.Create([1, 2, 3, 4, 5]))
.apply("Aggregate sum", AggregateSum())
)
# Write the output of the pipeline to a file
result | "Write output" >> beam.io.WriteToText("output.txt")
在上面的代码中,TimestampedValue
用于将元素与时间戳打包,并将其转换为一个(element, timestamp)
元组。然后,应用全局窗口,这将生成一个无界PCollection
。最后,将CombineGlobally
应用于数据并触发聚合操作。AfterWatermark
表示触发操作在指定时间段内完成后(例如,1秒后)执行,而AfterProcessingTime
表示触发操作在最后一个触发后指定时间段内完成后执行。AccumulationMode
定义CombineGlobally
的聚合模式,这里是默认的旁路模式。
该代码将总和聚合为单个输出
上一篇:BeamSQL - 输出文件为空