MapReduce序列化

什么是序列化:序列化就是将内存中的对象转化为其他可存储文件或可跨越计算机传输数据流的一种方式。

什么是反序列化:反序列化就是将收到的字节序列或者磁盘中的持久化数据转化为内存中的对象。

为什么要序列化:由于在运行程序的过程中,保存在内存中的对象会因为断电而丢失,或者在分布式系统中,对象需要由一台计算机传递给其他计算机进行计算,所以对象需要转化为文件或实际可传输的数据流。

为什么不用Java的序列化方式:Java序列化的方式实现java.io.Serializable接口,但是java的序列化是一个重量级序列化框架,他会附带很多额外的信息。因此Hadoop实现了自己的序列化机制,即实现org.apache.hadoop.io.Writable接口。

Hadoop序列化的特点:

        1、紧凑:高效使用存储空间
        2、快速:读写数据的额外开销小
        3、可扩展:随着通信协议的升级而可升级
        4、互操作:支持多种语言的交互

环境:Hadoop-3.0.0、IDEA、Maven

原始数据:http://链接:https://pan.baidu.com/s/1ohDP3-IeIQwcPpeUKWK95g?pwd=yyds 提取码:yyds

准备工作可参照:https://blog.csdn.net/m0_63716485/article/details/127597324?spm=1001.2014.3001.5502

由于Hadoop序列化的方法时实现org.apache.hadoop.io.Writable接口,因此我们首先编写writable类实现Writable接口:

import org.apache.hadoop.io.Writable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

public class writable implements Writable{
//数据 1	13736230513	192.196.100.1	www.atguigu.com	2481	24681	200
    public writable() {
        //空参构造
    }
    private long value1;
    private long value2;
    private long sumv;
    public long getSumv() {
        return sumv;
    }
    public void setSumv() {
        this.sumv = this.value1+this.value2;
    }
    public long getValue1() {
        return value1;
    }
    public void setValue1(long value1) {
        this.value1 = value1;
    }
    public long getValue2() {
        return value2;
    }
    public void setValue2(long value2) {
        this.value2 = value2;
    }
    public void write(DataOutput dataOutput) throws IOException {
        //重写序列化方法
        dataOutput.writeLong(value1);
        dataOutput.writeLong(value2);
        dataOutput.writeLong(sumv);
    }
    public void readFields(DataInput dataInput) throws IOException {
        //重写反序列化方法
        this.value1=dataInput.readLong();
        this.value2=dataInput.readLong();
        this.sumv=dataInput.readLong();
    }
    @Override
    public String toString() {
        return value1 + "\t" + value2 + "\t" + sumv + '\t';
    }
}

注意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 mapperx extends Mapper<LongWritable, Text,Text,writable>{
    Text t=new Text();
    writable w=new writable();
    @Override
    protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, writable>.Context context) throws IOException, InterruptedException {
        //获取对应行
        String l=value.toString();
        //分割
        String s[]=l.split("\t");
        //获取键值对
        String a=s[1];
        String b=s[s.length-3];
        String c=s[s.length-2];
        //封装
        t.set(a);
        w.setValue1(Long.parseLong(b));
        w.setValue2(Long.parseLong(c));
        w.setSumv();
        //写出
        context.write(t, w);
    }
}

Reduce类:

import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
public class reducerx extends Reducer<Text,writable,Text,writable> {
    writable o=new writable();
    @Override
    protected void reduce(Text key, Iterable<writable> values, Reducer<Text, writable, Text, writable>.Context context) throws IOException, InterruptedException {
        long totalvalue1=0;
        long totalvalue2=0;
        for(writable value:values){
            totalvalue1+=value.getValue1();
            totalvalue2+=value.getValue2();
        }
        o.setValue1(totalvalue1);
        o.setValue2(totalvalue2);
        o.setSumv();
        context.write(key, o);
    }
}

主程序入口:

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import java.io.IOException;
public class Main {
    public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
        //创建一个job
        Job job=Job.getInstance(new Configuration());
        job.setJarByClass(Main.class);
        //创建job的mapper和输出的类型
        job.setMapperClass(mapperx.class);
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(writable.class);
        //创建job的reduce和输出的类型
        job.setReducerClass(reducerx.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(writable.class);
        //创建job指定的输入和输出路径
        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        //执行任务
        job.waitForCompletion(true);
    }
}

注意2:在编写程序时要注意不要导错包

注意3:输入输出类型一致

结果展示:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值