2

处理映射到特定键的所有记录并为该数据输出多条记录的最简单方法是什么。

例如(一个综合示例),假设我的键是日期,值是带有测量温度的日内时间戳。我想将一天内的温度分类为高/平均/低(同样,低于/高于平均值的 1 个标准差)。

输出将是带有新分类的原始温度。

使用 Combine.PerKey(CombineFn) 允许使用 #extractOutput() 方法的每个键只输出一个。

谢谢

4

2 回答 2

5

CombineFns 被限制为单个输出值,因为这允许系统进行额外的并行化:分别组合值的不同子集,然后以任意树缩减模式组合它们的中间结果,直到为每个键生成单个结果值。

如果您的每个键的值不适合内存(因此您不能使用 Jeremy 建议的 GroupByKey-ParDo 模式)但计算的统计信息确实适合内存,您也可以执行以下操作:(1)使用组合。 perKey() 计算每天的统计数据 (2) 使用 View.asIterable() 将这些数据转换为 PCollectionViews。(3) 使用将统计信息作为辅助输入的 ParDo 重新处理原始输入 (4) 在 ParDo 的 DoFn 中,让 startBundle() 获取辅助输入并建立一个内存数据结构,将天数映射到可以使用的统计信息在 processElement 中进行查找。

于 2014-12-29T05:04:03.520 回答
1

为什么不使用 GroupByKey 操作后跟 ParDo?GroupBy 将使用给定键对所有值进行分组。然后应用 ParDo 允许您处理具有给定键的所有值。使用 ParDo,您可以为给定键输出多个值。

在您的温度示例中, GroupByKey 的输出将是 KV<Integer, Iterable<Float>> 的 PCollection (我假设您使用整数来表示温度的日期和浮点数)。然后,您可以应用 ParDo 来处理这些 KV 中的每一个。对于每个 KV,您可以迭代表示温度的浮点数并计算高/平均/低温。然后,您可以使用这些统计数据对每个温度读数进行分类,并输出代表分类的记录。这假设每天的测量次数足够小,可以轻松放入内存中。

于 2014-12-29T00:50:28.640 回答