不用看你的代码,是的,这在 MapReduce 中通常很容易做到;这里最好的情况是,如果您有很多用户(谁不想要这样?),并且每个用户的交互次数有限。
抽象地说,您的输入数据可能看起来像这样:
File 1:
1, 200, "/resource", "{metadata: [1,2,3]}"
File 2:
2, 200, "/resource", "{metadata: [4,5,6]}"
1, 200, "/resource", "{metadata: [7,8,9]}"
这只是用户、HTTP 状态、路径/资源和一些元数据的日志。您最好的选择是真正只专注于您的映射器清理数据,将其转换为您可以使用的格式,并将用户 ID 和其他所有内容(很可能再次包括用户 ID)作为键/值对发出。
我对 Hadoop Streaming 不是很熟悉,但根据文档:By default, the prefix of a line up to the first tab character is the key,
所以这可能看起来像:
1\t1, 200, "/resource", "{metadata: [7,8,9]}"
请注意,这1
是重复的,因为您可能希望在输出中使用它,而不仅仅是作为 shuffle 的一部分。这就是处理从单个映射器处理转变为File 1
更像File 2
:
1:
1, 200, "/resource", "{metadata: [1,2,3]}"
1, 200, "/resource", "{metadata: [7,8,9]}"
2:
2, 200, "/resource", "{metadata: [4,5,6]}"
如您所见,我们基本上已经完成了每个用户的 grep!这只是进行最终转换的问题,其中可能包括排序(因为这本质上是时间序列数据)。这就是为什么我之前说过如果你有很多用户和有限的用户交互,这对你来说会更好。对每个用户的大量 MB 进行排序(或通过网络发送!)不会特别快(尽管可能仍然比其他方法更快)。
总而言之,它取决于规模和用例,但通常,是的,这是一个非常适合映射/缩减的问题。