5.3.4 Hadoop序列化框架
序列化框架
除了writable实现序列化之外,只要实现让类型和二进制流相互转换,都可以作为hadoop的序列化类型,为此Hadoop提供了一个序列化框架接口,他们在org.apache.hadoop.io.serializer包中,Writable可以作为MapReduce支持的类型也是因为实现了这个框架接口。使用流程是定义序列化类实现框架接口->io.serializations参数配置序列化类名称,用一个逗号隔开的类名列表—> SerializationFactory构造函数中会读取配置,根据反射机制和类名创建序列化对象,保存在队列中—>通过SerializationFactory的函数getSerializer(Class<T> c)获取入序列化对象,入参是要获取对象的类名称。
在先来看看序列化开接口,以及writable是怎么实现的。
(1)序列化接口Serializer:
打开流,序列化,关闭流
public interface Serializer <T> {
void open(java.io.OutputStream outputStream) throws java.io.IOException;
void serialize(T t) throws java.io.IOException;
void close() throws java.io.IOException;
}
(2)反序列化接口:Deserializer
定义了一组接口,打开流,反序列化,关闭流
public interface Deserializer <T> {
void open(java.io.InputStream inputStream) throws java.io.IOException;
T deserialize(T t) throws java.io.IOException;
void close() throws java.io.IOException;
}
(3)序列化判断和实例获取接口
Accept函数判断是否支持序列化,要求是writable的子类,getSerializer函数返回序列化的实例,getDeserializer获取反序列化实例。通过实例调用接口函数去实现序列化函数。
public interface Serialization <T> {
boolean accept(java.lang.Class<?> aClass);
org.apache.hadoop.io.serializer.Serializer<T> getSerializer(java.lang.Class<T> tClass);
org.apache.hadoop.io.serializer.Deserializer<T> getDeserializer(java.lang.Class<T> tClass);
}
(4)定义序列化类
Writable定义序列化类要实现上面的三个接口, 实现接口中的序列化和反序列化函数。
public class WritableSerialization extends Configured
implements Serialization<Writable> {
//定义静态反序列化类
static class WritableDeserializer extends Configured
implements Deserializer<Writable> {
private Class<?> writableClass;
private DataInputStream dataIn;
//定义构造函数
public WritableDeserializer(Configuration conf, Class<?> c) {
setConf(conf);
this.writableClass = c;
}
//打开输入流
public void open(InputStream in) {
if (in instanceof DataInputStream) {
dataIn = (DataInputStream) in;
} else {
dataIn = new DataInputStream(in);
}
}
//反序列化函数,读取数据
public Writable deserialize(Writable w) throws IOException {
Writable writable;
if (w == null) {
writable
= (Writable) ReflectionUtils.newInstance(writableClass, getConf());
} else {
writable = w;
}
writable.readFields(dataIn);
return writable;
}
//关闭输入流
public void close() throws IOException {
dataIn.close();
}
}
序列化类
static class WritableSerializer implements Serializer<Writable> {
private DataOutputStream dataOut;
//打开输出流
public void open(OutputStream out) {
if (out instanceof DataOutputStream) {
dataOut = (DataOutputStream) out;
} else {
dataOut = new DataOutputStream(out);
}
}
序列化函数写入数据
public void serialize(Writable w) throws IOException {
w.write(dataOut);
}
//关闭输出流
public void close() throws IOException {
dataOut.close();
}
}
//判断是否是writable的子类
public boolean accept(Class<?> c) {
return Writable.class.isAssignableFrom(c);
}
//返回反序列化对象
public Deserializer<Writable> getDeserializer(Class<Writable> c) {
return new WritableDeserializer(getConf(), c);
}
//返回序列化对象
public Serializer<Writable> getSerializer(Class<Writable> c) {
return new WritableSerializer();
}
}
(5)序列化工厂
public class SerializationFactory extends Configured {
private static final Log LOG = LogFactory.getLog(SerializationFactory.class.getName());
private List<Serialization<?>> serializations = new ArrayList();
public SerializationFactory(Configuration conf) {
super(conf);
//通过读取配置信息conf中的io.serializations参数来确定Serializations,这个参数是一个逗号隔开的类名列表
String[] arr$ = conf.getStrings("io.serializations", new String[]{WritableSerialization.class.getName(), //默认包含Writable和Avro
AvroSpecificSerialization.class.getName(), AvroReflectSerialization.class.getName()});
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; ++i$) {
String serializerName = arr$[i$];
this.add(conf, serializerName);
}
}
//添加到list的函数
private void add(Configuration conf, String serializationName) {
try {
Class<? extends Serialization> serializionClass = conf.getClassByName(serializationName);
//根据类名和反射机制创建序列化对象,保存到 serializations的List中
this.serializations.add((Serialization)ReflectionUtils.newInstance(serializionClass, this.getConf()));
} catch (ClassNotFoundException var4) {
LOG.warn("Serialization class not found: ", var4);
}
}
public <T> Serializer<T> getSerializer(Class<T> c) {
Serialization<T> serializer = this.getSerialization(c);
return serializer != null ? serializer.getSerializer(c) : null;
}
public <T> Deserializer<T> getDeserializer(Class<T> c) {
Serialization<T> serializer = this.getSerialization(c);
return serializer != null ? serializer.getDeserializer(c) : null;
}
public <T> Serialization<T> getSerialization(Class<T> c) {
Iterator i$ = this.serializations.iterator();
Serialization serialization;
do {
if (!i$.hasNext()) {
return null;
}
serialization = (Serialization)i$.next();
} while(!serialization.accept(c));
return serialization;
}
}
其他序列化框架对比
|
ObjectInput(Out)Stream |
1.无法跨语言。内部私有的协议, 2.序列后的码流太大。java序列化的大小是二进制编码的5倍多! |
|
google的Protobuf |
1.结构化数据存储格式(xml,json等) |
|
faceBook的Thrift |
1.Thrift支持多种语言(C++,C#,Cocoa,Erlag,Haskell,java,Ocami,Perl,PHP,Python,Ruby,和SmallTalk) |
|
Kryo |
1.速度快,序列化后体积小 |
|
hessian |
1.默认支持跨语言 |
|
fst |
fst是完全兼容JDK序列化协议的系列化框架,序列化速度大概是JDK的4-10倍,大小是JDK大小的1/3左右。 |
|
Gson |
Gson是目前功能最全的Json解析神器, Gson的应用主要为toJson与fromJson两个转换函数,无依赖,不需要例外额外的jar,能够直接跑在JDK上。而在使用这种对象转换之前需先创建好对象的类型以及其成员才能成功的将JSON字符串成功转换成相对应的对象。类里面只要有get和set方法,Gson完全可以将复杂类型的json到bean或bean到json的转换,是JSON解析的神器。 |
|
FastJson |
Fastjson是一个Java语言编写的高性能的JSON处理器,由阿里巴巴公司开发。无依赖,不需要例外额外的jar,能够直接跑在JDK上。FastJson在复杂类型的Bean转换Json上会出现一些问题,可能会出现引用的类型,导致Json转换出错,需要制定引用。FastJson采用独创的算法,将parse的速度提升到极致,超过所有json库。 |

引用:
https://www.jianshu.com/p/937883b6b2e5
https://www.helplib.com/Java_API_Classes/article_62465
https://blog.csdn.net/lipeng_bigdata/article/details/51202764
自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取:
https://www.cnblogs.com/bclshuai/p/11380657.html
5.3.4 Hadoop序列化框架的更多相关文章
- hadoop深入研究:(十三)——序列化框架
hadoop深入研究:(十三)--序列化框架 Mapreduce之序列化框架(转自http://blog.csdn.net/lastsweetop/article/details/9376495) 框 ...
- hadoop压缩框架
一般来说,计算机处理的数据都存在一些冗余度,同时数据中间,尤其是相邻数据间存在着相关性,所以可以通过一些有别于原始编码的特殊编码方式来保存数据,使数据占用的存储空间比较小,这个过程一般叫压缩.和压缩对 ...
- Hadoop的简单序列化框架
Hadoop提供了一个加单的序列化框架API,用于集成各种序列化实现.该框架由Serialization实现. 其中Serialization是一个接口,使用抽象工厂的设计模式,提供了一系列和序列化相 ...
- 为什么hadoop中用到的序列化不是java的serilaziable接口去序列化而是使用Writable序列化框架
继上一个模块之后,此次分析的内容是来到了Hadoop IO相关的模块了,IO系统的模块可谓是一个比较大的模块,在Hadoop Common中的io,主要包括2个大的子模块构成,1个是以Writable ...
- Mapreduce之序列化框架(转自http://blog.csdn.net/lastsweetop/article/details/9376495)
框架简介 MapReduce仅仅可以支持Writable做key,value吗?答案是否定的.事实上,一切类型都是支持的,只需满足一个小小的条件:每个类型是以二进制流的形式传输.为此Hadoop提供了 ...
- 踏着前人的脚印学Hadoop——序列化,Writerable
package org.apache.hadoop.io; import java.io.DataOutput;import java.io.DataInput;import java.io.IOEx ...
- java序列化是什么和反序列化和hadoop序列化
1.什么是序列化和系列化DE- 神马是序列化它,序列化是内存中的对象状态信息,兑换字节序列以便于存储(持久化)和网络传输.(网络传输和硬盘持久化,你没有一定的手段来进行辨别这些字节序列是什么东西,有什 ...
- Hadoop序列化与Java序列化
序列化就是把内存中的对象的状态信息转换成字节序列,以便于存储(持久化)和网络传输 反序列化就是就将收到的字节序列或者是硬盘的持久化数据,转换成内存中的对象. 1.JDK的序列化 只要实现了serial ...
- Hadoop序列化机制及实例
序列化 1.什么是序列化?将结构化对象转换成字节流以便于进行网络传输或写入持久存储的过程.2.什么是反序列化?将字节流转换为一系列结构化对象的过程.序列化用途: 1.作为一种持久化格式. 2.作为一种 ...
随机推荐
- 数据格式转换string.Format
1.格式化货币(跟系统的环境有关,中文系统默认格式化人民币,英文系统格式化美元) string.Format("{0:C}",0.2) 结果为:¥0.20 (英文操作系统结果:$0 ...
- koa-router学习笔记
koa-router 是koa框架的一个路由处理级别的中间件. 目录结构 ├── app.js ├── middleware │ ├── m1.js │ └── m2.js ├── package-l ...
- 针对IE6 7 8当独写样式
IE8的格式: .foot{padding:12px 10px\9;} //在后面加\9 IE7的格式: .foot{*padding:12px 10px\9;} //在前面加* IE6的格式: .f ...
- 关于js异步的一些知识点
1,什么是单线程,和异步有什么关系 单线程-只有一个线程,只能做一件事 单线程的原因:避免DOM 渲染的冲突 浏览器需要渲染DOM JS 可以修改DOM 结构 JS 执行的时候,浏览器DOM 渲染会暂 ...
- reduce方法的使用
reduce(收敛):接收一个回调函数作为累加器,数组中的每个值(从左到右)开始缩减,最终为一个值,是ES5中新增的又一个数组逐项处理方法. reduce(callback,initialValue) ...
- SmartBinding实现DataSet与ListView的绑定及同步显示
kbmMW 5.10.10发布了,这个版本解决了我提出的问题,当对DataSet增删记录时,ListView能够同步显示.下面看看具体的实现代码. 为了解决上面的问题,作者为IkbmMWBinding ...
- FPGA学习笔记——点亮LED
软件平台:win7(64bit) + Quartus II 9.1 (64-Bit) 硬件平台:东理电子Easy-FPGA Cyclone II EP2C5T114C8N 这个开发板买了很长时间了,买 ...
- doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
在settings.py中增加 INSTALLED_APPS = [ ... 'django.contrib.sites', ] 问题就解决了.什么原因.——不知道.. 具体请看: https://s ...
- I2C总线、设备、驱动
I2C总线.设备.驱动 框架 I2C驱动框架可分为3个部分,分别是:I2C核心层.I2C总线驱动层(适配器层)以及I2C设备驱动层: I2C核心层 提供了统一的I2C操作函数,主要有两套函数smbus ...
- 【转】ufw 端口
1.扫描端口 用ubuntu自带的网络工具中的端口扫描不够强大,扫描结果可能不全,推荐用nmap,黑客常用的端口扫描利器!安装方法:sudo apt-get install nmap ,想扫描端口nm ...