mapreduce操作hbase ClassNotFoundException

解决mapreduce操作hbase ClassNotFoundException
博主在执行mapreduce操作hbase时遇到ClassNotFoundException,经过详细排查,发现是获取Hadoop Configuration对象时编码方式不同导致的问题。通过修改获取Configuration的方式,问题得到解决。此异常提醒我们需要更多关注源码细节。

mapreduce操作hbase ClassNotFoundException

小编今天碰到了一个非常奇怪的问题,在执行mapreduce时老是回报类找不到异常

java.lang.ClassNotFoundException: Class com.bcsix.hadoop.mapreduce.count.channel.app.Channel not found

在进行了种种排查之后束手无辞,检查打包的jar文件 我自己定义的com.bcsix.hadoop.mapreduce.count.channel.app.Channel明明存在,反编译之后的文件也是正确的,真是操蛋,这个异常竟然毫无破绽。

排查许久,始终搞不定。好了,该吃饭吃饭,该休息休息,管他娘的。

能这样悠闲那就好了,我的几个同事也遇到过这样的问题,最后把其他人的文件拷贝过去,竟然神奇的好了,这是肿么回事。难道程序员还和人品挂上勾了,这不可能。

好了写个hello world (单词统计) 同样的目录结构,同样的类名称,竟然能顺利执行。

现在能断定,这个异常肯定是和我的程序有关

对比hello world 和我当前出现异常的程序,首先给大家贴出驱动类

public class Main extends Configured implements Tool {

    // 数据源
    protected static final String OUT_TABLE = "tb_channel";
    protected static final String OUT_TABLE_FAMILY = "data";
    // 数据输出表
    protected static final String IN_TABLE = "tb_channel_app_count";
    protected static final String IN_TABLE_FAMILY = "data";

    @Override
    public int run(String[] param) throws Exception {

        Configuration conf = HBaseConfiguration.create();

        Job job = Job.getInstance(conf);
        job.setJarByClass(Main.class);

        Scan scan = new Scan();
        scan.addFamily(Bytes.toBytes(OUT_TABLE_FAMILY));
        TableMapReduceUtil.initTableMapperJob(OUT_TABLE, scan, Map.class,Text.class, Channel.class, job);

        //job.setReducerClass(Reduce.class);

        TableMapReduceUtil.initTableReducerJob(IN_TABLE, Reduce.class, job);

        return job.waitForCompletion(true) ? 0 : 1;
    }

    /**
     * 驱动方法
     */
    public static void main(String[] args) throws Exception {
        int ret = ToolRunner.run(new Main(), args);
        System.exit(ret);
    }

}

发现有两处地方有明显的差异

(1)获取 hadoop Configuration 对象的编码不同

hello world中获取 hadoop Configuration 编码如下:

getConf();  // Configuration conf = new Configuration();

出现异常的驱动方法中获取 hadoop Configuration 编码如下:

Configuration conf = HBaseConfiguration.create();

(2)hello world 和其他人写的示例中都有如下代码,出现异常的驱动方法中没有

job.setReducerClass(Reduce.class);

将(2)的这段设置编码加入到我的编码中测试,还是会有没有找到class异常

看来不是这儿的问题

最后将 (1)处 获取 hadoop Configuration 对象的编码修改成 getConf();

结果,结果竟然神奇的畅通执行了。

修改后的驱动类

public class Main extends Configured implements Tool {

    // 数据源
    protected static final String OUT_TABLE = "tb_channel";
    protected static final String OUT_TABLE_FAMILY = "data";
    // 数据输出表
    protected static final String IN_TABLE = "tb_channel_app_count";
    protected static final String IN_TABLE_FAMILY = "data";

    @Override
    public int run(String[] param) throws Exception {

        //Configuration conf = HBaseConfiguration.create();
        /**
         * 问题在这里              |||||||
         */
        Job job = Job.getInstance(getConf());
        job.setJarByClass(Main.class);

        Scan scan = new Scan();
        scan.addFamily(Bytes.toBytes(OUT_TABLE_FAMILY));
        TableMapReduceUtil.initTableMapperJob(OUT_TABLE, scan, Map.class,Text.class, Channel.class, job);


        TableMapReduceUtil.initTableReducerJob(IN_TABLE, Reduce.class, job);

        return job.waitForCompletion(true) ? 0 : 1;
    }

    /**
     * 驱动方法
     */
    public static void main(String[] args) throws Exception {
        int ret = ToolRunner.run(new Main(), args);
        System.exit(ret);
    }

}

真是一个神奇的异常,看来该多看看源码了。

这里是一个使用 MapReduce 统计 HBase 表中单科最高单科排名和总分排名的示例代码: ```java import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; public class HBaseRankCalculator { public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException { Configuration conf = HBaseConfiguration.create(); Job job = Job.getInstance(conf, "HBase Rank Calculator"); job.setJarByClass(HBaseRankCalculator.class); Scan scan = new Scan(); scan.setCaching(500); scan.setCacheBlocks(false); TableMapReduceUtil.initTableMapperJob( "student_scores", // 表名 scan, RankMapper.class, // Mapper 类 Text.class, // Mapper 输出 key 类型 IntWritable.class, // Mapper 输出 value 类型 job ); TableMapReduceUtil.initTableReducerJob( "student_ranks", // 输出表名 RankReducer.class, // Reducer 类 job ); job.setNumReduceTasks(1); // 设置 Reducer 个数 System.exit(job.waitForCompletion(true) ? 0 : 1); } } ``` Mapper 类 RankMapper 的代码: ```java import java.io.IOException; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.io.ImmutableBytesWritable; import org.apache.hadoop.hbase.mapreduce.TableMapper; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; public class RankMapper extends TableMapper<Text, IntWritable> { private final IntWritable ONE = new IntWritable(1); @Override public void map(ImmutableBytesWritable row, Result value, Context context) throws IOException, InterruptedException { // 从 value 中获取学生的单科成绩和总分 // 并将其作为 key 输出,将 value
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值