-
序列化
序列化是将结构化对象转换为字节流以通过网络传输或写入持久性存储的过程。
反序列化时将字节流转换成一些列结构化对象的过程。 -
java 序列化的特点
1、复杂且庞大
2、不能被分割(切片) -
hadoop 的序列化
1、紧凑
2、快速
3、可扩展性
4、互操作性 -
怎么实现 hadoop 的序列化呢?
序列化相关的接口:writable + comparable
1、int age数据基本数据类型,没有被hadoop序列化 int age = 18;
2、常用的数据类型hadoop已经序列化好了
我们只需要如下即可
方式一:
IntWritable iw = new IntWritable();
iw.set(age);
方式二:
IntWritable iw = new IntWritable(age);
-
自定义的数据类型的序列化
1、自定义对象的 hadoop 序列化必须实现 writable 接口
2、提供私有属性
3、提供无参和有参构造
4、提供 getter、setter 方法
5、重写序列化方法 write
6、重写反序列化方法 redaFileds
7、注意:反序列化字段的数据类型和顺序必须和序列化字段的数据类型和顺序一致
8、重写 tostring 方法 -
自定义的数据类型的序列化且排序
1、自定义对象可序列化且可排序,对象必须实现 WritableComparable 接口
2、提供私有属性
3、提供无参构造及有参构造
4、提供 setter、getter 方法
5、重写序列化方法 write
6、重写反序列化方法 readFields
7、注意:反序列化字段的数据类型和顺序必须和序列化字段的数据类型和顺序一致
8、重写 tostring 方法
练习
要求:我们创建一个User实体类,私有属性: age name address
这个类可以被hadoop序列化且按照年龄正序输出.
1、创建 springboot 项目
custom = https://start.aliyun.com
2、配置 pom.xml 文件
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.9.2</version>
</dependency>
3、编写代码
package chapter07.serialization;
import org.apache.hadoop.io.WritableComparable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
//1:自定义对象可序列化且可排序,对象必须实现 WritableComparable接口
//2:提供私有属性
//3:提供无参构造及有参构造
//4:提供setter and getter methods
//5: 重写序列化方法write 注意:反序列化字段的顺序必须和序列化字段的顺序一致
//6:重写反序列方法readFields
//7:重写compareTo方法
//8: 重写toString方法
//快捷键 alt+insert 可以提供setter
// 实现 WritableComparable 接口
public class StudentWritableComparable implements WritableComparable<StudentWritableComparable> {
private String name;
private int age;
private float score;
public StudentWritableComparable() {
}
// 序列化方法
@Override
public void write(DataOutput dataOutput) throws IOException {
dataOutput.writeUTF(name);
dataOutput.writeInt(age);
dataOutput.writeFloat(score);
}
// 反序列化方法 注意:反序列化字段的顺序必须和序列化字段的顺序一致
@Override
public void readFields(DataInput dataInput) throws IOException {
name = dataInput.readUTF();
age = dataInput.readInt();
score = dataInput.readFloat();
}
//重写比较排序函数
@Override
public int compareTo(StudentWritableComparable o) {
if (score > o.score) {
return 1;
} else if (score < o.score) {
return -1;
}
return 0;
}
//构造函数
public StudentWritableComparable(String name, int age, float score) {
this.name = name;
this.age = age;
this.score = score;
}
//toString 方法
@Override
public String toString() {
return name + "\t" + age + "\t" + score;
}
//生成 getter 和 setter 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public float getScore() {
return score;
}
public void setScore(float score) {
this.score = score;
}
}
-
为什么要压缩?
1、减少文件的存储空间
2、加快数据传输 -
gzip:是 linux 和 hadoop 默认的压缩格式。
不能切片,它适合低于 128M 的数据压缩,但是它的压缩效率排第二,压缩速率排第三 -
lzo:需要安装,且压缩可以被切割,压缩效率排第三,速度排第二
-
snappy:需要安装,且压缩不可以被切割, 压缩效率排第四,速度排第一,而且它的速度远远快于第二名
-
bzip2:不需要安装,且压缩可以被切割,压缩效率第一,速度排第四
-
我们应该怎么选择呢?
snappy 在文件不要切割的情况下优先
lzo 在文件需要切割的情况下优先 -
压缩工具(数据编码器) org.apache.hadoop.io.compress.Compressor
-
解压工具(数据解码器) org.apache.hadoop.io.compress.Decompressor
-
hadoop 适合处理什么样的数据呢?
社会处理大的文件,不适合处理小的文件。 -
如何处理小的文件呢?
将一些列小文件,组合成一个大文件进行处理。 -
这个大文件我们称它为:容器.统一对小文件进行存储。
-
hadoop 提供了两种容器:SequenceFile、MapFile
-
SequenceFile:序列文件 what ?
SequenceFile 是 Hadoop API 提供的一种二进制文件支持。
这种二进制文件直接将 <key, value> 对序列化到文件中,key 是任意的 Writable,value 是任意的 Writable
基本思路就是将小文件进行合并成一个大文件,同时对这些小文件的位置信息构建索引,需要注意的是 key 是没有经过排序的
优点:
支持压缩:Record 压缩 或 Block 压缩
本地化任务支持
难度低 -
MapFile 文件可以看做是存储有序 key-value 的 SequenceFile 文件,MapFile 文件保证 key-value 的 key 是有序(基于 key)。
这种有序是由用户来保证的
一旦写入的 key-value 不符合 key 的非递减顺序,则会直接报错而不是自动的去堆输入的 key-value 排序
MapFile 文件的本质实际上则是由两个 SequenceFile 文件组成,一个用来存储 key-value 数据(/data),一个用来存储 key-value 的位置索引(/index)
转载:https://blog.csdn.net/qq_52354698/article/details/128794645