赞
踩
题目:MapReduce编程初级实践 |
---|
实验环境: 操作系统:ubuntu16.04 hadoop版本:1.2.1(伪分布式) JDK版本:1.8 Eclipse 3.8 |
解题思路: 1. 编程实现文件合并和去重操作。 【注释】数据去重的最终目标是让原始数据中出现次数超过一次的数据在输出文件中只出现一次。由于shuffle过程会有合并相同key值记录的过程,会想到将不同文件中相同内容数据的Key设置成一样的,即是Map处理后是一样的,然后把交给Reduce,无论这个数据的value-list是怎么样,只要在最终结果输出它的key就行了。 2. 编写程序实现对输入文件的排序。 【注释】MapRedcue有默认排序规则:按照key值进行排序的,如果key为封装int的IntWritable类型,那么MapReduce按照数字大小对key排序。所以在Map中将读入的数据转化成IntWritable型,然后作为key值输出(value任意)。reduce拿到之后,将输入的key作为value输出,并根据value-list中元素的个数决定输出的次数。 3. 对给定的表格进行信息挖掘。 【注释】分析题意可知这是要进行单表连接。考虑到MapReduce的Shuffle过程会将相同的Key值放在一起,所以可以将Map结果的Key值设置成待连接的列,然后列中相同的值就自然会连接在一起了。具体而言,就是是左表的parent列和右表的child列设置成Key,则左表中child(即为结果中的grandchild)和右表中的parent(即为结果中的grandparent)。为了区分输出中的左、右表,需要在输出的value-list中再加入左、右表的信息,比如,在value的String最开始处加上字符1表示左表,加上字符2表示右表。这样设计后,Reduce接收的中每个key的value-list包含了grandchild和grandparent关系。取出每个Key的value-list进行解析,将右表中的child放入一个数组,左表中的parent放入另一个数组,然后对两个数组求笛卡尔积就是最后的结果。 |
实验内容: 1. 编程实现文件合并和去重操作。 对于两个输入文件,即文件A和文件B,请编写MapReduce程序,对两个文件进行合并,并剔除其中重复的内容,得到一个新的输出文件C。下面是输入文件和输出文件的一个样例供参考。 关键代码: 2. 编写程序实现对输入文件的排序。 现在有多个输入文件,每个文件中的每行内容均为一个整数。要求读取所有文件中的整数,进行升序排序后,输出到一个新的文件中,输出的数据格式为每行两个整数,第一个数字为第二个整数的排序位次,第二个整数为原待排列的整数。下面是输入文件和输出文件的一个样例供参考。 关键代码: 3. 对给定的表格进行信息挖掘。 下面给出一个child-parent的表格,要求挖掘其中的父子辈关系,给出祖孙辈关系的表格。 关键代码: |
解决方案(列出遇到的问题和解决办法,列出没有解决的问题): 1.第一个实验“数据去重”在检验代码无错的情况下,输出的结果却把两个文件的所有数据给输出来了,数据重合的数据并没有合并。 解决方法:经过认真分析程序逻辑和输出结果,发现问题出现在不同文件中一行数据之间的空格不同,由于“数据去重”的合并过程是相同字符串的就合在一起,所以在不同文件中一行数据之间的空格不同的情况下,shuffle会把这两个本应合并的字符串认为是两个字符串,故出现了错误的结果。 2.出错代码如下: org.apache.hadoop.mapreduce.ReduceContext$ValueIterator cannot be cast to org.apache.commons.math.util.OpenIntToDoubleHashMap$Iterator。 解决方法:首先分析到出问题的代码是这两段:Iterator ite=(Iterator) values.iterator();String record=((java.util.Iterator) ite).next().toString();可以看出,第一段代码强制类型转换得到是org.apache.commons.math.util.OpenIntToDoubleHashMap$Iterator而下面要用到的是java.util.Iterator,所以修改第一段代码为java.util.Iterator ite=values.iterator();问题解决。 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。