Hadoop-MapReduce之自定义数据类型

以下是自定义的一个数据类型,有两个属性,一个是名称,一个是开始点(可以理解为单词和单词的位置)

MR程序就不写了,请看WordCount程序。

package cn.genekang.hadoop.mr.RealignerTargetCreator;

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

import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;

public class ReadBean implements WritableComparable<ReadBean> {
    /**
     * 自定义的一个数据类型。
     * 此数据类型可以作为key,也可以作为value
     * 如果只作为value的话而且不需要排序的话可以继承自Writable接口。如果需要排序的话就必须实现WritableComparable接口
     * 如果作为key的话,还必须要指定以什么作为key,或者说需要告诉shuffle,你的key值是怎么进行比较的。
     * 以此,必须要定义一个Comparator的比较类,继承自 WritableComparator,而且要有定义key的比较器
     * **/
    private String locName;
    private int readStart;

    public ReadBean() {
        // TODO Auto-generated constructor stub
    }

    //必须重写此方法,将属性进行序列化处理
    @Override
    public void write(DataOutput out) throws IOException {
        out.writeUTF(locName);
        out.writeInt(readStart);
    }

    //必须重写此方法,反序列化,得到属性的值
    @Override
    public void readFields(DataInput in) throws IOException {
        this.locName = in.readUTF();
        this.readStart = in.readInt();

    }

    //此方法是重写Object类的,可以不重写
    @Override
    public int hashCode() {
        return locName.hashCode() * 13 + readStart;
    }

    //要想对数据进行排序,必须重写此方法。1为升序,-1为降序,0为相等
    @Override
    public int compareTo(ReadBean o) {
        if (this.locName.equals(o.getLocName())) {
            return this.readStart > o.readStart ? 1 : -1;
        } else {
            return this.locName.compareTo(o.locName) > 0 ? 1 : -1;
        }

    }

    //必须要重写,指明自定义数据类型的输出格式和输出内容
    @Override
    public String toString() {
        return this.locName +"\t"+ this.readStart;
    }

    //可以不重写
    public boolean equals(ReadBean o) {

        if (this.locName.equals(o.getLocName())
                && this.readStart == o.getReadStart()) {

            return true;
        }
        return false;

    }

    //可以使用此方法为自定义数据类型赋值。
    public void set(String name, int start) {
        this.locName = name;
        this.readStart = start;
    }

    public String getLocName() {
        return locName;
    }

    public void setLocName(String locName) {
        this.locName = locName;
    }

    public int getReadStart() {
        return readStart;
    }

    public void setReadStart(int readStart) {
        this.readStart = readStart;
    }

    //定义一个内部的比较类,实现key的比较方法
    public static class Comparator extends WritableComparator {
        public Comparator() {
            super(ReadBean.class);
            // TODO Auto-generated constructor stub
        }

        @Override
        public int compare(byte[] arg0, int arg1, int arg2, byte[] arg3,
                int arg4, int arg5) {
            return compareBytes(arg0, arg1, arg2, arg3, arg4, arg5);
        }

    }

    //定义一个key的比较器
    static {
        WritableComparator.define(ReadBean.class, new Comparator());
    }

}
时间: 2024-12-29 04:33:14

Hadoop-MapReduce之自定义数据类型的相关文章

结合手机上网流量业务来说明Hadoop中的自定义数据类型(序列化、反序列化机制)

大家都知道,Hadoop中为Key的数据类型必须实现WritableComparable接口,而Value的数据类型只需要实现Writable接口即可:能做Key的一定可以做Value,能做Value的未必能做Key.但是具体应该怎么应用呢?--本篇文章将结合手机上网流量业务进行分析. 先介绍一下业务场景:统计每个用户的上行流量和,下行流量和,以及总流量和. 本次描述所用数据: 日志格式描述: 日志flowdata.txt中的具体数据: 接下来贴出详细代码,代码中含有详细注释,从代码中可以看出,

Hadoop读书笔记(六)MapReduce自定义数据类型demo

Hadoop读书笔记(一)Hadoop介绍:http://blog.csdn.net/caicongyang/article/details/39898629 Hadoop读书笔记(二)HDFS的shell操作:http://blog.csdn.net/caicongyang/article/details/41253927 Hadoop读书笔记(三)Java API操作HDFS:http://blog.csdn.net/caicongyang/article/details/41290955

Hadoop 学习自定义数据类型

(学习网易云课堂Hadoop大数据实战笔记) 序列化在分布式环境的两大作用:进程间通信,永久存储. Writable接口, 是根据 DataInput 和 DataOutput 实现的简单.有效的序列化对象. MR的任意Value必须实现Writable接口: MR的key必须实现WritableComparable接口,WritableComparable继承自Writable和Comparable接口: (本节先讲自定义value值,下一节再讲自定义key值,根据key值进行自定义排序) 以

干货--Hadoop自定义数据类型和自定义输入输出格式整合项目案例

正文开始前 ,先介绍几个概念 序列化 所谓序列化,是指将结构化对象转化为字节流,以便在网络上传输或写到磁盘进行永久存储. 反序列化 是指将字节流转回到结构化对象的逆过程 序列化在分布式数据处理的两个大领域经常出现:进程间通信和永久存储 在Hadoop中,系统中多个节点上进程间的通信是通过"远程过程调用"(remote procedure call,RPC)实现的 .RPC协议将消息序列化成二进制流后发送到远程节点,远程节点接着将二进制流反序列化为原始消息 Hadoop使用了自己写的序列

Hadoop mapreduce自定义分组RawComparator

本文发表于本人博客. 今天接着上次[Hadoop mapreduce自定义排序WritableComparable]文章写,按照顺序那么这次应该是讲解自定义分组如何实现,关于操作顺序在这里不多说了,需要了解的可以看看我在博客园的评论,现在开始. 首先我们查看下Job这个类,发现有setGroupingComparatorClass()这个方法,具体源码如下: /** * Define the comparator that controls which keys are grouped toge

[Hadoop] - Mapreduce自定义Counter

在Hadoop的MR程序开发中,经常需要统计一些map/reduce的运行状态信息,这个时候我们可以通过自定义Counter来实现,这个实现的方式是不是通过配置信息完成的,而是通过代码运行时检查完成的. 1.创建一个自己的Counter枚举类. enum PROCESS_COUNTER { BAD_RECORDS, BAD_GROUPS; } 2.在需要统计的地方,比如map或者reduce阶段进行下列操作. context.getCounter(PROCESS_COUNTER.BAD_RECO

hadoop mapreduce 自定义InputFormat

很久以前为了满足公司的需求写过一些自定义InputFormat,今天有时间拿出来记一下     需求是这样的,如果如果使用FileInputFormat作为输入,是按照行来读取日志的,也就是按照\n来区分每一条日志的,而由于一条日志中记录着一些错误信息,比如java的异常信息,这些信息本身就带有换行符,如果还是按照\n进行区分每一条日志的话明显是错误的,由于我们日志的特殊性,将以"]@\n"作为区分日志的标识.     接下来就来看看如何自定义InputFormat,还是不画类图了,我

hadoop学习;自定义Input/OutputFormat;类引用mapreduce.mapper;三种模式

hadoop分割与读取输入文件的方式被定义在InputFormat接口的一个实现中,TextInputFormat是默认的实现,当你想要一次获取一行内容作为输入数据时又没有确定的键,从TextInputFormat返回的键为每行的字节偏移量,但目前没看到用过 以前在mapper中曾使用LongWritable(键)和Text(值),在TextInputFormat中,因为键是字节偏移量,可以是LongWritable类型,而当使用KeyValueTextInputFormat时,第一个分隔符前后

Hadoop 自定义数据类型

Hadoop的自定制数据类型有两种,一种较为简单的是针对值,另外一种更为完整针对于键和值都适合 一.针对值,实现 Writable 接口 package org.apache.hadoop.io; import java.io.DataOutput; import java.io.DataInput; import java.io.IOException; public interface Writable { void write(DataOutput out) throws IOExcept

hadoop MapReduce自定义分区Partition输出各运营商的手机号码

MapReduce和自定义Partition MobileDriver主类 package Partition; import org.apache.hadoop.io.NullWritable; import org.apache.hadoop.io.Text; public class MobileDriver { public static void main(String[] args) { String[] paths = {"F:\\mobile.txt", "F