0 Java序列化反序列化概念:
JVM把数据写到JVM管理范畴之外, 然后将这些数据读回来放在JVM管理范畴内时,
需要一些处理才能被识别,写出去就是序列化,读取回JVM管理范畴内就是反序列化
0.1 Java序列化的不足:
1.不精简。附加Java序列化的不足:
1.不精简。附加信息多。不大适合随机访问。
2.存储空间大。递归地输出类的超类描述直到不再有超类。序列化图对象,反序列化时为每个对象新建一个实例。相反。Writable对象可以重用。
3.扩展性差。而Writable方便用户自定义信息多。不大适合随机访问。
4. 总结一句话:
Java的序列化是面向对象 有继承关系,就是将这个对象是祖宗十八代全给序列化和反序列化,很费空间
0.2 Hadoop序列化的特点
紧凑:高效使用存储空间。
快速:读写数据的额外开销小
可扩展:可透明地读取老格式的数据
互操作:支持多语言的交互
0.3 Hadoop序列化在分布式环境中的作用:
进程间通讯,永久存储
Hadoop节点间通信
0.4 Hadoop序列化鼻祖Writable:
Writable接口, 是根据 DataInput 和 DataOutput 实现的简单、有效的序列化对象.
MR的任意Key和Value必须实现Writable接口.
public interface Writable { void write(DataOutput out) throws IOException; void readFields(DataInput in) throws IOException; } public interface WritableComparable<T> extends Writable, Comparable<T> { }
0.5 常见的Writable实现类:
0.6 java类型和hadoop类型相互转化:
java--->hadoop | hadoop--->java | |
String | new LongWritable(123L); | get() |
非String | new Text(String str) | toString() |
0.7 java 基本类型和hadoop Writable实现类对比图:
hadoop是做大数据的,为何这么吝啬于简洁版本的序列化??
正是因为操作大数据,数据之间从map节点到reduce节点传输时,才要更小的开销IO流。
以达到快速的目的。
1 Hadoop自定义类型:
class KpiWritable1 implements Writable{ 因为操作的是流,先写入的就要先读出来 long upPackNum; // 上传数据包个数 long downPackNum;// 下载数据包个数 long upPayLoad;// 上传数据 long downPayLoad;// 下载数据 public KpiWritable1(String upPackNum,String downPackNum,String upPayLoad,String downPayLoad){ this.upPackNum = Long.parseLong(upPackNum); this.downPackNum = Long.parseLong(downPackNum); this.upPayLoad = Long.parseLong(upPayLoad); this.downPayLoad = Long.parseLong(downPayLoad); } public KpiWritable1(){} @Override public void write(DataOutput out) throws IOException { // 先写后读 out.writeLong(this.upPackNum); out.writeLong(this.downPackNum); out.writeLong(this.upPayLoad); out.writeLong(this.downPayLoad); } @Override public void readFields(DataInput in) throws IOException { // 读取的时候, 按照写方法的顺序( 队列方式) 顺序读取 this.upPackNum = in.readLong(); this.downPackNum = in.readLong(); this.upPayLoad = in.readLong(); this.downPayLoad = in.readLong(); } @Override public String toString() { return upPackNum + "\t" + downPackNum + "\t" + upPayLoad + "\t" + downPayLoad; } }
2 Writable接口实现类查看源码
发现 都是基本类型的比较
LongWritable: /** Compares two LongWritables. */ @Override public int compareTo(LongWritable o) { long thisValue = this.value; long thatValue = o.value; return (thisValue<thatValue ? -1 : (thisValue==thatValue ? 0 : 1)); } Text: mr处理中文的时候 使用u8方式 文字以binarybytes比较 /**This class stores text using standard UTF8 encoding. ...*/ public class Text extends BinaryComparable implements WritableComparable<BinaryComparable> { protected CharsetDecoder initialValue() { return Charset.forName("UTF-8").newDecoder(). ArrayWritable 里面是对数组的封装 NullWritable 输入和写出方法都是空
Text: mr处理中文的时候 使用u8方式 文字以binarybytes比较