复合密钥

mkh04yzy  于 2021-06-03  发布在  Hadoop
关注(0)|答案(2)|浏览(434)

假设我有一个制表符分隔的文件,其中包含如下格式的用户活动数据:

timestamp  user_id  page_id  action_id

我想编写一个hadoop作业来统计每个页面上的用户操作,因此输出文件应该如下所示:

user_id  page_id  number_of_actions

我需要一些类似于复合键的东西-它将包含用户id和页面id。有什么通用的方法可以用hadoop来实现这一点吗?我找不到任何有用的东西。到目前为止,我在mapper中发出这样的键:

context.write(new Text(user_id + "\t" + page_id), one);

这是可行的,但我觉得这不是最好的解决办法。

carvr3hs

carvr3hs1#

写你自己的 Writable . 在您的示例中,解决方案可以如下所示:

public class UserPageWritable implements WritableComparable<UserPageWritable> {

  private String userId;
  private String pageId;

  @Override
  public void readFields(DataInput in) throws IOException {
    userId = in.readUTF();
    pageId = in.readUTF();
  }

  @Override
  public void write(DataOutput out) throws IOException {
    out.writeUTF(userId);
    out.writeUTF(pageId);
  }

  @Override
  public int compareTo(UserPageWritable o) {
    return ComparisonChain.start().compare(userId, o.userId)
        .compare(pageId, o.pageId).result();
  }

}

虽然我觉得你的身份证可能是个 long ,给你 String 版本。基本上只是在 Writable 接口,请注意它需要默认构造函数,因此您应该始终提供一个。
这个 compareTo 逻辑清楚地告诉我们如何对数据集进行排序,同时也告诉reducer哪些元素是相等的,以便对它们进行分组。 ComparisionChain 是Guava的好原料。
别忘了重写equals和hashcode!分区器将通过键的哈希代码来确定缩减器。

yrefmtwq

yrefmtwq2#

您可以编写自己的类来实现writable和writablecomparable,以比较这两个字段。
皮埃尔卢克贝特朗

相关问题