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比较