我现在在本地模式下使用Pig 0.11.1,从CSV加载数据。
到目前为止,我已经能够加载我们的数据集并对其执行所需的计算。下一步是从数据中取一些样本并执行相同的计算。要复制现有流程,我们希望每十五分钟抓一个数据点。
这就是问题所在。我可以在Pig中编写一个过滤器,如果数据点恰好是十五分钟的间隔,那么它将匹配,但我如何获取接近十五分钟边界的数据点呢?
我需要查看十五分钟的标记并抓住那里的记录。如果该标记上没有记录(最有可能),那么我需要在标记后抓取下一条记录。
我想我需要编写自己的Filter UDF,但似乎UDF需要是有状态的,以便它知道在时间间隔之后何时找到第一个匹配。我还没有找到任何有状态UDF的例子,而且我可以告诉它可能是一个坏主意,因为我们不知道在最终针对Hadoop运行时数据是如何映射/减少的。
我可以通过存储键/时间戳值并编写一个可解析它们的Python脚本,在几个步骤中完成此操作。不过,我真的希望尽可能多地保留Pig中的这个过程。
修改:最基本的数据如下:{id:long, timestamp:long}
。 timestamp
以毫秒为单位。每组数据都在timestamp
上排序。如果记录X在最小timestamp
(开始时间)之后完全落在15分钟的边界上,请抓住它。否则,在那15分钟的边界之后抓住下一条记录,无论何时可能。我没有关于预期结果的好例子,因为我没有时间手工整理数据。
答案 0 :(得分:1)
在MapReduce中满足条件可能会很棘手“否则,在15分钟的边界之后抓住下一条记录,无论何时可能”,但是如果你稍微改变一下“在15分钟之前抓住前一条记录”边界“比它可能很容易。这个想法是15分钟是900000毫秒,因此我们可以将记录分组到覆盖900000毫秒的组中,对它们进行排序并取得最高记录。以下是我头脑中的脚本示例:
inpt = LOAD '....' AS (id:long, timestamp:long);
intervals = FOREACH inpt GENERATE id, timestamp, timestamp / 900000 as interval;
grp = GROUP intervals BY interval;
result = FOREACH grp {
sort = ORDER intervals BY timestamp DESC;
top = LIMIT ord 1;
GENERATE FLATTEN(top);
};