Hadoop - 复合键

Jac*_*ski 11 hadoop composite-key

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

timestamp  user_id  page_id  action_id
Run Code Online (Sandbox Code Playgroud)

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

user_id  page_id  number_of_actions
Run Code Online (Sandbox Code Playgroud)

我需要像复合键这样的东西 - 它将包含user_id和page_id.使用hadoop有没有通用的方法呢?我找不到任何有用的东西.到目前为止,我在mapper中发出这样的键:

context.write(new Text(user_id + "\t" + page_id), one);
Run Code Online (Sandbox Code Playgroud)

它有效,但我觉得这不是最好的解决方案.

Tho*_*lut 14

只是撰写自己的作品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();
  }

}
Run Code Online (Sandbox Code Playgroud)

虽然我认为你的ID可能是一个long,但你有String版本.基本上只是Writable界面上的正常序列化,请注意它需要默认的构造函数,所以你应该总是提供一个.

compareTo逻辑告诉显然是如何排序的数据集,也告诉减速器什么元素是相等的,使他们能够进行分组.

ComparisionChain番石榴的好工具.

不要忘记重写equals和hashcode!分区器将通过密钥的哈希码确定reducer.