一、概述
Avro是一种远程过程调用和数据序列化框架,是在Apache的Hadoop项目之内开发的。它使用JSON来定义数据类
型和通讯协议,使用压缩二进制格式来序列化数据。它主要用于Hadoop,它可以为持久化数据提供一种序列化格
式,并为Hadoop节点间及从客户端程序到Hadoop服务的通讯提供一种电报格式。
二、序列化和反序列化
概述
数据序列化就是将对象或者数据结构转化成特定的格式,使其可在网络中传输,或者可存储在内存或者文件中。反
序列化则是相反的操作,将对象从序列化数据中还原出来。
数据序列化的重点在于数据的交换和传输 。
衡量标准
- 序列化之后的数据大小
因为序列化的数据要通过网络进行传输或者是存储在内存或者文件中,所以数据量越小,则存储或者传输所
用的时间就越少 - 序列化以及反序列化的耗时及占用的CPU
- 是否能够跨语言或者平台
因为现在的企业开发中,一个项目往往会使用到不同的语言来进行架构和实现。那么在异构的网络系统中,
网络双方可能使用的是不同的语言或者是不同的操作系统,例如一端使用的是Java而另一端使用的C++;或者
一端使用的是Windows系统而另一端使用的是Linux系统,那么这个时候就要求序列化的数据能够在不同的语
言以及不同的平台之间进行解析传输
Java原生序列化/反序列化机制的问题
- Java的原生序列化不能做到对象结构的服用,就导致序列化多个对象的时候数据量较大
- Java的原生序列化在使用的时候,是按照Java指定的格式将对象进行解析,解析为字节码格式,那么此时其他
的语言在接收到这个对象的时候,是无法解析或者解析较为困难。即Java的原生序列化机制是没有做到跨语言
或者跨平台传递使用
三、常见序列化框架
Protobuf
Protobuf是Google公司提供的序列化/反序列化框架,特点如下:
- 平台无关、语言无关。
- 二进制、数据自描述。
- 提供了完整详细的操作API。
- 高性能,比xml要快20-100倍
- 尺寸小,比xml要小3-10倍,高可扩展性
- 数据自描述、前后兼容
Thrift
Thrift是Facebook公司提供的序列化/反序列化的框架,2007年贡献给了Apache。特点如下:
- 支持非常多的语言绑定
- thrift文件生成目标代码,简单易用、
- 消息定义文件支持注释
- 数据结构与传输表现的分离,支持多种消息格式
- 包含完整的客户端/服务端堆栈,可快速实现RPC
- 支持同步和异步通信
三、Avro的特点
- 丰富的数据结构类型,8种基本数据类型以及6种复杂类型
- 快速可压缩的二进制形式
- 提供容器文件用于持久化数据
- 远程过程调用RPC框架
- 简单的动态语言结合功能,Avro 和动态语言结合后,读写数据文件和使用 RPC协议都不需要生成代码,而代
码生成作为一种可选的优化只值得在静态类型语言中实现。而代码生成作为一种可选的优化只值得在静态类
型语言中实现。
通过avro,每次进行序列化,根据模式(schema)文件来序列化,可以提高性能。
Avro是依赖于模式(schema),模式文件是用json格式来表示的。如果是想利用avro实现序列化或rpc通信,需要
遵守schema的格式要求。基于模式的好处是使得序列化快速而又轻巧
四、Avro的格式说明
简单类型
Avro定义了8种简单数据类型,下表是其简单说明:
Avro类型 | 说明 |
---|---|
null | 没有值 |
boolean | 一个二级制布尔值 |
int | 32位有符号整数 |
long | 64位有符号整数 |
float | 32位单精度浮点数 |
double | 64位双精度浮点数 |
bytes | 8位无符号字节序列 |
string | 字符序列 |
复杂格式
Avro定义了六种复杂数据类型,每一种复杂数据类型都具有独特的属性,下表就每一种复杂数据类型进行说明。
每一种复杂数据类型都含有各自的一些属性,其中部分属性是必需的,部分是可选的。
这里需要说明Record类型中field属性的默认值,当Record Schema实例数据中某个field属性没有提供实例数据
时,则由默认值提供,具体值见下表。Union的field默认值由Union定义中的第一个Schema决定。
五、Avro的序列化与反序列化
- 创建Maven工程,导入Avro的依赖
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro-ipc</artifactId>
<version>1.7.5</version>
</dependency>
完整的pom.xml文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.test.avro</groupId>
<artifactId>Avro</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Avro</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<compiler-plugin.version>2.3.2</compiler-plugin.version>
<avro.version>1.7.5</avro.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test<