学习 MapReduce 和 HDFS 的知识,基于这些知识实践一个实际的应用,即共同关注查找系统。用户可以提供一个包含用户及其关注列表的数据集,系统会通过 MapReduce 处理这些数据,找到每一位用户两两之间的共同关注。
FindFrinedsOne的思路:求两两之间有共同好友,及他俩的共同好友都是谁。例子:张三-谢霆锋:陈奕迅,伊森:即张三和谢霆锋的共同关注有陈奕迅和伊森。把好友当作key,value是拥有key好友的用户,找出拥有张三的所有人员。
FindFrinedsTwo的思路:在第一步结果后,双重for循环进行两两之间进行拼接后实现本项目需求。将计算得到的结果保存在 HDFS 或本地文件系统上,提供给用户查询。
FindFrinedsOne:Mapper类,输入数据中的用户及其关注列表进行了处理。通过冒号分割,我们提取出拥有好友的用户名和该用户的好友列表,进一步将每位好友作为键,其所属用户作为值的键值对输出至上下文。这个Mapper类在整个流程中扮演着关键的角色,为后续的数据计算和共同关注的查找奠定了基础。
FindFrinedsTwo:Mapper类,该 Mapper 接收了第一阶段输出的数据,通过以制表符分割的方式提取好友信息和拥有该好友的用户列表。为了避免计算中的数据重复,它对用户列表进行了排序。随后,在双重循环的迭代中,该 Mapper 生成了每两个用户之间的共同关注的键值对。其中,键是两个用户的组合,值是它们共同关注的好友。这个过程确保了对于同一组用户,无论出现在哪个位置,都会生成相同的键值对,避免了重复计算。
FindFrinedsOne:Reduce类,通过 reduce 方法,它接收到了每位好友及其拥有该好友的用户列表。在处理过程中,它将所有用户列表整合成一个字符串,并与好友的名字连接,形成最终的输出结果。第一阶段 Reducer 类的设计使得最终的输出清晰明了,每一行都表示一位好友及其拥有该好友的用户列表。最后输出的结果的组织形式为第二阶段的处理提供了清晰的输入数据,为计算每两位用户之间的共同关注关系奠定了基础。这样的结果不仅方便后续阶段的处理,也为用户提供了直观且易于理解的信息。
FindFrinedsTwo:Reduce类,通过 reduce 方法,它接收到每两位用户之间的共同关注的键值对,其中键表示两位用户的组合,值是这些用户共同关注的好友列表。在处理过程中,它将所有好友列表整合成一个字符串,并与键连接,形成最终的输出结果。第二阶段 Reducer 类的设计使得最终的输出清晰明了,每一行都表示两位用户之间的共同关注关系,以及这些用户共同关注的好友列表。这种结果的组织形式方便后续的查询与分析,为用户提供了直观且易于理解的共同关注信息。
定义了 Text 类型的变量 v 作为输出的值。reduce 方法是 MapReduce 中的 Reducer 阶段的核心方法。Text, Text, Text, Text 表示输入和输出的键值对的类型。在 reduce 方法中,接收到的 key 是第一阶段 Mapper 阶段生成的好友关系,values 则是拥有这位好友的所有用户。
通过循环遍历 values,将拥有同一好友的用户列表整合为一个字符串。使用 StringUtils.join 方法将用户列表连接为一个字符串,以逗号分隔。将生成的字符串与 key 连接,并输出到上下文。这样,最终的输出就是每位好友及其拥有该好友的用户列表。
定义了 Text 类型的变量 k 作为输出的键。使用 NullWritable 表示输出的值为 null(因为我们只关心键),reduce 方法是 MapReduce 中的 Reducer 阶段的核心方法。Text, Text, Text, NullWritable 表示输入和输出的键值对的类型。在 reduce 方法中,接收到的 key 是第二阶段 Mapper 阶段生成的用户组合,values 则是这两位用户共同关注的好友。
通过循环遍历 values,将共同关注的好友列表整合为一个字符串。使用 StringUtils.join 方法将共同关注的好友列表连接为一个字符串,以逗号分隔。将生成的字符串与 key 连接,并输出到上下文。这样,最终的输出就是每两位用户组合及其共同关注的好友列表的字符串。
输入键值对:
K(键):LongWritable(行偏移量),V(值):Text(每行文本)。
处理过程:Mapper 通过解析每行文本,提取用户及其关注列表,生成键值对。其中K:Text(用户),V:Text(关注列表)。
输出键值对:K:Text(好友),V:Text(拥有该好友的用户)。
输入键值对:K:Text(好友),V:Iterable
处理过程:Reducer 将拥有同一好友的用户列表整合为一个字符串。其中K:Text(好友),V:Text(拥有该好友的用户列表)。
输出键值对:K:Text(好友),V:Text(拥有该好友的用户列表字符串)。
输入键值对:K:Text(好友),V:Text(拥有该好友的用户列表字符串)。
处理过程:Mapper 解析输入,生成每两位用户之间的组合和共同关注好友列表。K:Text(用户组合),V:Text(共同关注好友)。
输出键值对:K:Text(用户组合),V:Text(共同关注好友)。
输入键值对:K:Text(用户组合),V:Iterable
处理过程:Reducer 将共同关注好友列表整合为一个字符串。K:Text(用户组合),V:NullWritable(用于标识没有实际值)。
输出键值对:K:Text(用户组合),V:NullWritable。
输出结果:
目的:
第一阶段的目的是统计每个用户的关注列表,并整合为键值对。第二阶段的目的是计算每两位用户之间的共同关注好友,并整合为键值对。
数据类型变化:
在第一阶段,键值对的变化是从用户和关注列表到好友和拥有该好友的用户列表字符串。在第二阶段,键值对的变化是从好友和拥有该好友的用户列表字符串到用户组合和共同关注好友列表。
这样的设计和变化使得整个 MapReduce 过程在不同阶段能够有效地处理数据,从而实现了共同好友查找系统的功能。
详细代码:
数据集:
张三:谢霆锋,陈奕迅,邓昊天,风清扬,伊森,奥布莱恩
谢霆锋:张三,陈奕迅,伊森,柯南
陈奕迅:张三,谢霆锋,邓昊天,伊森,艾弗森
邓昊天:张三,伊森,风清扬,李世民
伊森:谢霆锋,陈奕迅,邓昊天,莫言,李世民
风清扬:张三,谢霆锋,陈奕迅,邓昊天,伊森,奥布莱恩,莫言
乔治:张三,陈奕迅,邓昊天,伊森,风清扬
何仙姑:张三,陈奕迅,邓昊天,伊森,奥布莱恩
艾弗森:张三,奥布莱恩
姜东南:谢霆锋,奥布莱恩
柯南:张三,陈奕迅,邓昊天
李世民:邓昊天,伊森,风清扬
莫言:伊森,风清扬,乔治
奥布莱恩:张三,何仙姑,艾弗森,姜东南
package com.gyx.mr;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat; // 添加导入语句
import org.apache.hadoo