当输出是多个字段是,需要使用对象来表示,此时这个对象要序列化
序列化概念
Java 的序列化是一个重量级序列化框架(Serializable),一个对象被序列化后,会附带很多额外的信息(各种校验信息,Header,继承体系等),不便于在网络中高效传输。所以,Hadoop 自己开发了一套序列化机制(Writable)
在编写MapReduce程序时,我们会发现,对于MapReduce的输入输出数据(key-value),我们只能使用Hadoop提供的数据类型,而不能使用Java本身的基本数据类型,比如,如果数据类型为long,那么在编写MR程序时,对应Hadoop的数据类型则为LongWritable。关于原因,简单说明如下:hadoop在节点间的内部通讯使用的是RPC,RPC协议把消息翻译成二进制字节流发送到远程节点,
远程节点再通过反序列化把二进制流转成原始的信息。也就是说,传递的消息内容是需要经过hadoop特定的序列化与反序列化操作的,因此,才需要使用hadoop提供的数据类型,当然,如果想要自定义MR程序中key-value的数据类型,则需要实现相应的接口,如Writable、WritableComparable接口
也就是说,如果需要自定义key-value的数据类型,必须要遵循如下的原则:
/**
* MapReduce的任意的key和value都必须要实现Writable接口
* MapReduce的任意key必须实现WritableComparable接口,WritableComparable是Writable的增强版
* key还需要实现Comparable的原因在于,对key排序是MapReduce模型中的基本功能
*/
常用数据类型对应的 Hadoop 数据序列化类型
自定义序列化数据类型的步骤
(1)必须实现Writable接口
(2)反序列化时,需要反射调用空参构造函数,所以必须有空参构造
(3)重写序列化方法
(4)重写反序列化方法
(5)注意反序列化的顺序和序列化的顺序完全一致
(6)要想把结果显示在文件中,需要重写 toString(),可用 \t 分开,方便后续用
(7)如果需要将自定义的 bean 放在 key 中传输,则还需要实现Comparable 接口,因为 MapReduce 框中的 Shuffle 过程要求对 key 必须能排序
在MapReduce中,要求被序列化的对象对应的类中必须提供无参构造在MapReduce中,要求被序列化的对象的属性值不能为null
案例统计每个手机号的上下行流量
手机号,上行流量,下行流量 peopleinfo.t