MapReduce调试(无输出调试)

一、问题

由于上一个程序,有一些行数并不会得到处理,但是通过观测代码,以及数据的人工处理,并没有发现代码有任何问题,因此希望通过调试的方式去找出原因;但是在Windows下,我们并不能直接的运行我们的程序,因此,我们需要使用apache的mrunit的单元测试工具。

二、加载配置文件

之前的环境以及相关的配置由上一个博客讲到https://blog.csdn.net/qq_40304825/article/details/91038975

我们可以通过访问网站https://mvnrepository.com/artifact/org.apache.mrunit/mrunit/1.1.0,得到相应的配置,但是我们需要添加一个我们自己版本的<classifier>hadoop2</classifier>

添加mrunit配置,向pom.xml中添加如下信息,并点击Import Changes(在Even Log中)

<dependency>
            <groupId>org.apache.mrunit</groupId>
            <artifactId>mrunit</artifactId>
            <version>1.1.0</version>
            <classifier>hadoop2</classifier>
            <scope>test</scope>
        </dependency>

配置成功后,我们会在项目中看到如下的文件夹,我们需要在该文件夹下面添加我们的test

三、编写代码(代码详细解释,在前面一篇文章)

(1)Mapper代码

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

import java.io.IOException;


public class FriendCountMapper extends Mapper<LongWritable, Text,Text, FriendCountBean> {
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String data = value.toString();
        String[] userAndFriends = data.split("\t");
        //获得用户和该用户的朋友们
        if (userAndFriends.length != 2){
            System.err.println(key.toString()+"行不成功");
            return;
        }
        String user = userAndFriends[0];
        String[] friends = userAndFriends[1].split(",");
        for (String friend:friends) {
            context.write(new Text(user), new FriendCountBean(friend, true));
            context.write(new Text(friend), new FriendCountBean(user, true));
        }
        for (int i = 0;i < friends.length; i++){
            for (int j = i+1 ;j < friends.length; j++){
                context.write(new Text(friends[i]), new FriendCountBean(friends[j], false));
                context.write(new Text(friends[j]), new FriendCountBean(friends[i], false));
            }
        }
    }
}

(2)FriendCountBean(这个不需要怎么看)

import org.apache.hadoop.io.Writable;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;


public class FriendCountBean implements Writable {
    String name;
    boolean isFriend;

    public FriendCountBean(String name, boolean isFriend) {
        this.name = name;
        this.isFriend = isFriend;
    }

    public FriendCountBean() {
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        FriendCountBean that = (FriendCountBean) o;
        return isFriend == that.isFriend &&
                name.equals(that.name);
    }


    public String getName() {
        return name;
    }

    public boolean isFriend() {
        return isFriend;
    }

    public void write(DataOutput dataOutput) throws IOException {
        dataOutput.writeUTF(name);
        dataOutput.writeBoolean(isFriend);
    }

    public void readFields(DataInput dataInput) throws IOException {
        this.name = dataInput.readUTF();
        this.isFriend = dataInput.readBoolean();
    }
}

注意:如果想与输出结果进行对比的话,自定义的类,一定要写equals方法和hashCode方法。

(3)Test代码(代码解释在注释中)

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mrunit.mapreduce.MapDriver;
import org.junit.Before;
import org.junit.Test;

import java.io.*;

public class FriendCountTest {
    //mrunit有个好处就是,我们只需要测试map,reduce或者mapReduce,我们只需要建立相关的Driver即可
    //这里我只想测试map,因此我只创建它的Driver
    private MapDriver<LongWritable, Text,Text, FriendCountBean> mapDriver;

    //这个是将我们类指定到Driver中,一定要写注释Before
    @Before
    public void setUp() throws Exception {
        mapDriver = MapDriver.newMapDriver(new FriendCountMapper());
    }

    //真正的测试函数,我们运行时候,需要在这个方法体内点右击,然后再Run,因为我们没有写main函数,所以直接运行类的话,没有函数入口
    @Test
    public void testMap() {
        //要测试的数据,存在这个txt中,最好不要用绝对路径(我只是图个方便)
        File dataFile = new File("C:\\Users\\admin\\IdeaProjects\\hadoop-bootstrap\\src\\test\\data\\social_data.txt");
        BufferedReader reader = null;
        Long count = 1L;
        try {
            //正常的文件读取顺序
            reader = new BufferedReader(new FileReader(dataFile));
            String line = null;
            while ((line = reader.readLine()) != null){ //将我们的测试用例一直添加进去
                //这里注意,一定要和我们创建的Mapper对象的输入一致,前两个参数
                //同理,如果我们写withOutput,也要和Mapper的后两个参数一致
                mapDriver.withInput(new LongWritable(count), new Text(line));
                count++;
            }
            try{
                //这个test是以多线程的形式跑的,因此,我们只需要在这里运行一次,他就会自动调用输入,并运行
                mapDriver.runTest();
            } catch (Throwable throwable){
                //由于我们没有写Output,因此程序会报error,所有的error都来自于Throwable
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

然后,我们可以通过打断点的形式,对程序进行调试,就像java程序一样。

但是,最终运行了这个程序,并不会报相关的错误,因此觉得有可能是由于在hadoop集群中的文件编码与windows的编码格式不太一样,导致了相应的错误,只需要修改相应编码即可。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值