本帖最后由 爱动的蜗牛 于 2015-11-3 21:22 编辑 Alkaloid0515 发表于 2015-11-3 11:51 大神,你好,你的那个参考,我很仔细的看了,收益匪浅,谢谢。我这个是join reduce。。。。。因为是单表,所以首先将表拆分为分为左表和右表,在map输出时,选择合并的键作为key。 左表加“2”表示,取父母名字做为key: 右表加“1”表示,取孩子名字做为key: 在map输出后的shuffle阶段,会将相同key的value的值连接,而两表合并发生在reduce中,合并的原则是:对于同一个key,如果同时存在于左右表中,即可合并。例如:对于左表“2 Jone Lucy”和右表“1 Lucy Mary“,因为key=Lucy,同时存在于两个表中,即Lucy是Jone的父母,还是Mary的儿女,自然Jone是Mary是孙子,所以合并这两个表啊
取出符合合并原则的孙子们的姓名与祖父母们的姓名,然后执行计算的卡迪儿积,
将结果输出,这就是这个逻辑,是有一点混乱哈,菜鸟刚接触,所以很多不会,但是今天看了你的回帖再仔细看看自己的程序,还是没找到在哪错的,期待您的回复 |
爱动的蜗牛 发表于 2015-11-2 22:41 楼主思维有点胡乱,没看出是join map,还是join reduce。 对于数据量小的可以先join map,也就是把数据作为两份输入,然后在map端join。 public static class MapJoinMapper extends Mapper<LongWritable, Text, NullWritable, Emp_Dep> { private Map<Integer, String> joinData = new HashMap<Integer, String>();//这个是join的关键 @Override protected void setup(Mapper<LongWritable, Text, NullWritable, Emp_Dep>.Context context) throws IOException, InterruptedException { // 预处理把要关联的文件加载到缓存中 Path[] paths = DistributedCache.getLocalCacheFiles(context.getConfiguration()); // 我们这里只缓存了一个文件,所以取第一个即可,创建BufferReader去读取 BufferedReader reader = new BufferedReader(new FileReader(paths[0].toString())); String str = null; try { // 一行一行读取 while ((str = reader.readLine()) != null) { // 对缓存中的表进行分割 String[] splits = str.split("\t"); // 把字符数组中有用的数据存在一个Map中 joinData.put(Integer.parseInt(splits[0]), splits[1]); } } catch (Exception e) { e.printStackTrace(); } finally{ reader.close(); } } @Override protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, NullWritable, Emp_Dep>.Context context) throws IOException, InterruptedException { // 获取从HDFS中加载的表 String[] values = value.toString().split("\t"); // 创建Emp_Dep对象 Emp_Dep emp_Dep = new Emp_Dep(); // 设置属性 emp_Dep.setName(values[0]); emp_Dep.setSex(values[1]); emp_Dep.setAge(Integer.parseInt(values[2])); // 获取关联字段depNo,这个字段是关键 int depNo = Integer.parseInt(values[3]); // 根据depNo从内存中的关联表中获取要关联的属性depName String depName = joinData.get(depNo); // 设置depNo emp_Dep.setDepNo(depNo); // 设置depName emp_Dep.setDepName(depName); // 写出去 context.write(NullWritable.get(), emp_Dep); } } 详细参考: MapReduce表连接操作之Map端join |
输入数据是这样的: child parent Jone Lucy Tom Lucy Tom Jack Jone Jack Lucy Mary Lucy Ben Jack Alice Jack Jesse Terry Alice Terry Jesse Philip Terry 要求输出: |