MapReduce初级案例——单表关联
作者:虾皮
前面的实例都是在数据上进行一些简单的处理,为进一步的操作打基础。“ 单表关联”这个实例要求从给出的数据中寻找所关心的数据,它是对原始数据所包含信息的挖掘。下面进入这个实例。
1 实例描述
实例中给出 child-parent(孩子——父母)表,要求输出 grandchild-grandparent(孙子——爷奶)表。
样例输入如下所示。
file:
家族树状关系谱:
样例输出如下所示。
file:
2 设计思路
分析这个实例,显然需要进行单表连接,连接的是左表的 parent 列和右表的 child 列,且左表和右表是同一个表。
连接结果中除去连接的两列就是所需要的结果——“ grandchild–grandparent”表。要用MapReduce 解决这个实例, 首先应该考虑如何实现表的自连接; 其次就是连接列的设置;最后是结果的整理。
考虑到 MapReduce 的 shuffle 过程会将相同的 key 会连接在一起,所以可以将 map 结果的 key 设置成待连接的列,然后列中相同的值就自然会连接在一起了。再与最开始的分析联系起来:
要连接的是左表的 parent 列和右表的 child 列,且左表和右表是同一个表,所以在 map阶段将读入数据分割成 child 和 parent 之后,会将 parent 设置成 key, child 设置成 value进行输出,并作为左表;再将同一对 child 和 parent 中的 child 设置成 key, parent 设置成value 进行输出,作为右表。
为了区分输出中的左右表,需要在输出的 value 中再加上左右表的信息,比如在 value 的 String 最开始处加上字符 1 表示左表,加上字符 2 表示右表。
这样在 map 的结果中就形成了左表和右表,然后在 shuffle 过程中完成连接。 reduce 接收到连接的结果,其中每个 key 的 value-list 就包含了“ grandchild–grandparent”关系。
取出每个key 的 value-list 进行解析,将左表中的 child 放入一个数组, 右表中的 parent 放入一个数组,然后对两个数组求笛卡尔积就是最后的结果了。
3 程序代码
程序代码如下所示。
4 代码结果
1)准备测试数据
通过 Eclipse 下面的“ DFS Locations”在“ /user/hadoop”目录下创建输入文件“ STjoin_in”文件夹( 备注:“ STjoin_out”不需要创建。)如图 4.4-1 所示,已经成功创建。
然后在本地建立一个 txt 文件,通过 Eclipse 上传到“ /user/hadoop/STjoin_in”文件夹中,一个 txt 文件的内容如“实例描述”那个文件一样。如图 4.4-2 所示,成功上传之后。
从 SecureCRT 远处查看“ Master.Hadoop”的也能证实我们上传的文件,显示其内容如
图 4.4-3 所示:
2)运行详解
( 1) Map 处理:
map 函数输出结果如下所示。
( 2) Shuffle 处理
在 shuffle 过程中完成连接。
首先由语句“ 0 != grandchildnum && 0 != grandparentnum”得知,只要在“ value-list”中没有左表或者右表,则不会做处理,可以根据这条规则去除无效的 shuffle 连接。
然后根据下面语句进一步对有效的 shuffle 连接做处理。
针对一条数据进行分析:
分析结果: 左表用“ 字符 1”表示, 右表用“ 字符 2”表示,上面的<key, value-list=””>
中的“ key”表示左表与右表的连接键。而“ value-list”表示以“ key”连接的左表与右表的
相关数据。
根据上面针对左表与右表不同的处理规则,取得两个数组的数据如下所示:
然后根据下面语句进行处理。
处理结果如下面所示:
其他的有效 shuffle 连接处理都是如此。
3)查看运行结果
这时我们右击 Eclipse 的“ DFS Locations”中“ /user/hadoop”文件夹进行刷新,这时会发现多出一个“ STjoin_out”文件夹,且里面有 3 个文件,然后打开双其“ part-r-00000”文件,会在 Eclipse 中间把内容显示出来。如图 4.4-4 所示。
End.