Avro是一种远程过程调用和数据序列化框架,是在Apache的Hadoop项目之内开发的。它使用JSON来定义数据类
型和通讯协议,使用压缩二进制格式来序列化数据。它主要用于Hadoop,它可以为持久化数据提供一种序列化格
式,并为Hadoop节点间及从客户端程序到Hadoop服务的通讯提供一种电报格式。
数据序列化就是将对象或者数据结构转化成特定的格式,使其可在网络中传输,或者可存储在内存或者文件中。反
序列化则是相反的操作,将对象从序列化数据中还原出来。
数据序列化的重点在于数据的交换和传输 。
Protobuf是Google公司提供的序列化/反序列化框架,特点如下:
Thrift是Facebook公司提供的序列化/反序列化的框架,2007年贡献给了Apache。特点如下:
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决定。
<dependency>
<groupId>org.apache.avrogroupId>
<artifactId>avroartifactId>
<version>1.7.5version>
dependency>
<dependency>
<groupId>org.apache.avrogroupId>
<artifactId>avro-ipcartifactId>
<version>1.7.5version>
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.0modelVersion>
<groupId>cn.test.avrogroupId>
<artifactId>AvroartifactId>
<version>0.0.1-SNAPSHOTversion>
<packaging>jarpackaging>
<name>Avroname>
<url>http://maven.apache.orgurl>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<compiler-plugin.version>2.3.2compiler-plugin.version>
<avro.version>1.7.5avro.version>
properties>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.10version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-simpleartifactId>
<version>1.6.4version>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.apache.avrogroupId>
<artifactId>avroartifactId>
<version>1.7.5version>
dependency>
<dependency>
<groupId>org.apache.avrogroupId>
<artifactId>avro-ipcartifactId>
<version>1.7.5version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>${compiler-plugin.version}version>
plugin>
<plugin>
<groupId>org.apache.avrogroupId>
<artifactId>avro-maven-pluginartifactId>
<version>1.7.5version>
<executions>
<execution>
<id>schemasid>
<phase>generate-sourcesphase>
<goals>
<goal>schemagoal>
<goal>protocolgoal>
<goal>idl-protocolgoal>
goals>
<configuration>
<sourceDirectory>${project.basedir}/src/main/avro/sourceDirectory>
<outputDirectory>${project.basedir}/src/main/java/outputDirectory>
configuration>
execution>
executions>
plugin>
plugins>
build>
project>
{
"namespace":"avro.pojo",
"type":"record",
"name":"Person",
"fields":
[
{"name":"username", "type":"string"},
{"name":"age", "type":"int"},
{"name":"no", "type":"string"}
]
}
@Test
public void write() throws Exception{
User u1=new User("Ken Tompson",194375);
User u2=new User("丹尼斯·里奇",194170);
DatumWriter<User> dw=new SpecificDatumWriter<>(User.class);
DataFileWriter<User> dfw=new DataFileWriter<>(dw);
// 创建底层的文件输出通道
// schema - 序列化类的模式
// path - 文件路径
dfw.create(u1.getSchema(),new File("1.txt"));
// 把对象数据写到文件中
dfw.append(u1);
dfw.append(u2);
dfw.close();
}
@Test
public void read() throws Exception{
DatumReader<User> dr=
new SpecificDatumReader<>(User.class);
DataFileReader<User> dfr=
new DataFileReader<>(new File("1.txt"),dr);
//--通过迭代器,迭代出对象数据
while(dfr.hasNext()){
System.out.println(dfr.next());
}
}
RPC 的全称是 Remote Procedure Call(远程过程调用) 是一种进程间通信方式。它允许程序调用另一个地址空
间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。 即程序员无论
是调用本地的还是远程的,本质上编写的调用代码基本相同。
布鲁斯·纳尔逊1974年毕业于哈维·穆德学院,1976年在斯坦福大学获得计算机科学硕士学位,1982年在卡内基梅
隆大学获得计算机科学博士学位。在追求博士学位时,他开发了远程过程调用(RPC)的概念。他和他的合作者安
德鲁·伯雷尔因在RPC方面的工作而获得了1994年ACM软件系统奖。1996他加入思科系统担任首席科学官。
<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.0modelVersion>
<groupId>cn.test.avrogroupId>
<artifactId>AvroclientartifactId>
<version>0.0.1-SNAPSHOTversion>
<packaging>jarpackaging>
<name>Avroclientname>
<url>http://maven.apache.orgurl>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<compiler-plugin.version>2.3.2compiler-plugin.version>
<avro.version>1.7.5avro.version>
properties>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.10version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-simpleartifactId>
<version>1.6.4version>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.apache.avrogroupId>
<artifactId>avroartifactId>
<version>1.7.5version>
dependency>
<dependency>
<groupId>org.apache.avrogroupId>
<artifactId>avro-ipcartifactId>
<version>1.7.5version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>${compiler-plugin.version}version>
plugin>
<plugin>
<groupId>org.apache.avrogroupId>
<artifactId>avro-maven-pluginartifactId>
<version>1.7.5version>
<executions>
<execution>
<id>schemasid>
<phase>generate-sourcesphase>
<goals>
<goal>schemagoal>
<goal>protocolgoal>
<goal>idl-protocolgoal>
goals>
<configuration>
<sourceDirectory>${project.basedir}/src/main/avro/sourceDirectory>
<outputDirectory>${project.basedir}/src/main/java/outputDirectory>
configuration>
execution>
executions>
plugin>
plugins>
build>
project>
@namespace("rpc.service")
protocol AddService{
int add(int i,int y);
}
如果想要传递的是一个对象,则约束如下:
@namespace("rpc.service")
protocol TransferService{
import schema "User.avsc";
void parseUser(avro.domain.User user);
}
如果想要传递一个map,并且map里包含一个对象的代码:
@namespace("rpc.service")
protocol MapService{
import schema "User.avsc";
void parseUserMap(map<avro.domain.User> userMap);
}
public class Start {
public static void main(String[] args) throws Exception {
NettyTransceiver client=new NettyTransceiver(
new InetSocketAddress("127.0.0.1",8888));
//--因为接口不能直接使用,avro底层是通过jdk动态代理生成接口的代理对象
AddService proxy=
SpecificRequestor.getClient(AddService.class, client);
int result=proxy.add(2, 3);
System.out.println("客户端收到结果:"+result);
}
}
public class AddServiceImpl implements AddService{
@Override
public int add(int a, int b) throws AvroRemoteException {
return a+b;
}
}
public class Start {
public static void main(String[] args) {
System.out.println("服务端启动");
NettyServer server=new NettyServer(
new SpecificResponder(AddService.class,
new AddServiceImpl()),
new InetSocketAddress(8888));
}
}
上一篇 3.大数据学习之旅——Zookeeper