Java中的mapreduce没了_MapReduce学习踩坑指南

MapReduce学习踩坑指南

关于java及jar包的import问题

踩坑1

错误: 程序包org.apache.hadoop.conf不存在

或者其他的类似于程序包org.apache.hadoop.*不存在的问题

如果你出现 找不到org.apache.commons.cli.Options的类文件 这个错误,请在maven\repository\commons-cli\commons-cli找到一个commons-cli.jar并导入!

原因

其实提示这种错误是正确的,当你在使用java -cp提交,并且Configuration configuration = new Configuration(); 没有添加集群配置文件的时候,我们使用的是本地模式,为什么?因为 Configuration加载配置文件的顺序是先添加core-default.xml,core-site.xml这两个文件,但是是使用hadoop jar 或者 yarn jar 才会去hadoop 的 /etc/hadoop 目录下找配置文件。如果你使用java -cp 他是找不到得出,自然就是本地模式了。

简单来讲就是你导入的jar包找!不!到!

解决方法

1.javac -cp 你安装jar包的目录\hadoop-common-3.0.0.jar;hadoop-mapreduce-client-core-3.0.0.jar;hadoop-mapreduce-client-common-3.0.0.jar Name.java一般来讲需要

f5dda026cdfddfc1f34c8c2e259a734a.png

这几个jar包就可以了

注意:对于.class文件来说,只需要指明包的路径即可;但是对于jar文件来说,必须要指定全路径即路径+文件名的格式,不能只指定一个路径。

2.使用批处理将jar包导入calsspath(待填坑)

输入输出类型不匹配

踩坑2

这个错误并不是什么大的错误,也不具有普遍的意义,记下来主要是提醒自己不要犯同样的简单的错误,并不具有普遍参考价值

Type mismatch in value from map: expected org.apache.hadoop.io.DoubleWritable, received org.apache.hadoop.io.IntWritable

d382bcbf17a7a198d49d790332842acd.png

看到这个我都傻了,为啥输入输出不匹配啊,啊,是我的java文件写错了,改!

8abbedc929a25d0680e0447684c49470.png

👆我改的就是它QAQ

改完之后再运行,还是报错???!

实!!际!!上!!

运行用的代码hadoop jar ./Stu.jar StuAvg /input /output运行的其实是这个jar包,所以改这个java文件时没用的!!!!

how foolish ME!!

再贴一下整个的文件

f5c1561f4dea7432df57a4e07f3a88b3.png

解决方法

改动的应该是Stu.jar,应该通过重新在ide中build再把jar包复制过来才行

这么个破错我改了2个小时.......

399e9bf6ce9f41ba00b4611401a828f5.png

自定义序列化对象输出失败

3.踩坑3

java.io.IOException: Initialization of all the collectors failed. Error in last collector was:java.lang.ClassCast

66bd6cc80b86e453a03e953ccb722a85.png

原因

二次排序,说mapreduce内置默认的排序功能,突然恍然大悟,曾经学习TreeMap和TreeSet的时候,也有排序的要求,我们自定义的类,如果没有实现两个对象大小比较的方法,就没有自动排序功能可言,

而以上我自定义的Person作为Map输出的key,也需要这样的比较功能,而Writable只是Hadoop对序列化和反序列化的加强,要能实现比较功能,需要实现的类是WritableComparable接口,

然后重写其compareTo方法.果不其然,修改了代码以后,就可以得到正确的结果了.

简单来说就是我们自己写的TextArrayWritable没有实现实现WritableComparable接口,造成Map序列化失败导致本错误

解决

自定义的序列化对象作为MapReduce的key输出的时候,需要实现WritableComparable接口,从写compareTo方法.

更正:能不要自定义KEY对象就别定义了,太麻烦了……,要实现一大堆接口ArrayWritable也最好别作为KEY使用,会出现序列化失败(java.io.IOException: Initialization of all the collectors failed.)的问题,我最后还是采用了Text作为KEY,简单多了……,我会把原来的错的代码也贴上来,提醒自己不要自己造轮子

示例

public int compareTo(Person o) {

int res = o.getId()-this.id;

return res==0?1:res;//如果返回0,表示这两个对象是相等的,而要求key不能相等.所以如果等于0,就按先来后到存进去咯

}

Ps:我也不想自己实现这个ArrayWritable类的,但是作业要求两个值作为键值,我也没什么办法,头秃,如果看到这句话的你有啥好办法还请务必告诉我QAQ

编码问题(UTF-8与GBK)

踩坑4

map无法正确分类,mainput有数据而mapoutput无输出,经检查是map函数中的字符串比对检查条件出了问题

包括各类hadoop输出中文乱码,控制台输出乱码,条件判断失败等

原因

hadoop内部强制使用UTF-8,而windows的控制台默认使用GBK导致输出乱码

解决方法

1.chcp 65001 将当前窗口强制使用UTF-8的编码,可以解决输出乱码的问题

2.对比条件含中文字符 我也不知道咋办,先挖个坑,会了就回来填坑(笑)

我!回!来!了!

比较的编码问题应该是在java源程序在编译时未指定编码格式造成编译结果中的中文乱码!

解决的话在编译时加上-encoding utf-8就可以了!

一点碎碎念:u1s1我学的是基础的分布式编程方法和思想,在编码问题上出问题也太难受了吧……就没什么道理

官方示例代码

import java.io.IOException;

import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.Path;

import org.apache.hadoop.io.IntWritable;

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.output.FileOutputFormat;

import org.apache.hadoop.util.GenericOptionsParser;

public class WordCount {

//mapper方法的重写

public static class TokenizerMapper

extends Mapper{

/*继承了Mapper类,其中KEYIN,VALUEIN为输入的键和值

KEYOUT,VALUEOUT为输出的键和值,需要注意的是,Java自带的数据类型在序列化时效率较低,为提高序列化效率

应使用hadoop序列化数据类型

Long:LongWritable

String:Text

Integer:IntWritable

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值